TW
Tripwire
Find contracts. Test them. Review real vulns.

Analysis Run

019d5666-e916-7246-acfd-c2f7d6ef4d74

complete
Chain ID
1
Address
Block Number
Created
Sat, Apr 4, 2026 2:51 AM
Review Summary

What survived the funnel

Open this run to answer one question: is this real attacker-relevant behavior with real impact, or just normal contract plumbing?

Confirmed
0
Validated
0
Source
Verified
Review Backing
Present
Best current signal
Untrusted CALL target/value reachable
crit 0 high 0 direct contract
Review Checklist
1. Read the findings table first. Ignore raw jobs until the result looks real.
2. Confirm attacker control, not just the existence of a sink.
3. Confirm money or privilege impact.
4. Keep it if the behavior is real. Kill it if this is normal proxy, admin, or upgrade plumbing.

Processing Jobs

Status & attempts
ID Type Status Attempts Heartbeat
42960 artifact.fetch complete 1 / 3 1 week ago
42961 proxy.resolve complete 1 / 3 1 week ago
42962 tool.cast_disasm complete 1 / 3 1 week ago
42963 analysis.bundle complete 1 / 3 1 week ago
42964 capability.graph complete 1 / 3 1 week ago
42965 detector.run complete 1 / 3 1 week ago
42966 validation.fork complete 1 / 3 1 week ago
43008 report.consolidate complete 1 / 6 1 week ago
43009 tool.slither complete 1 / 2 1 week ago

Artifact

Runtime bytecode: available
Creation TX:
Deployer:
Proxy: no not_proxy
Implementation:
Verified Source: yes
Proxy evidence
{
    "status": "not_proxy"
}

Slither

tool.slither
Status
complete
Attempts
1 / 2
Findings
2
Solc
0.8.27 (solc-select)
View stderr
'forge clean' running (wd: /tmp/slither-3rzqsamt)
'forge config --json' running
'forge build --build-info --skip ./test/** ./script/** --force' running (wd: /tmp/slither-3rzqsamt)

Wallets.refundGasBySchain(bytes32,address,uint256,bool) (contracts/test/TestWallets.sol#53-68) sends eth to arbitrary user
	Dangerous calls:
	- spender.transfer(amount) (contracts/test/TestWallets.sol#67)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#functions-that-send-ether-to-arbitrary-destinations

MathUpgradeable.mulDiv(uint256,uint256,uint256) (@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol#55-134) has bitwise-xor operator ^ instead of the exponentiation operator **: 
	 - inverse = (3 * denominator) ^ 2 (@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol#116)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-exponentiation

SkaleVerifierMock.verify(IFieldOperations.Fp2Point,bytes32,uint256,uint256,uint256,IFieldOperations.G2Point) (contracts/test/SkaleVerifierMock.sol#57-99) uses a Boolean constant improperly:
	-require(bool,string)(G1Operations.isG1Point(hashA,hashB) || true,Hash not in G1) (contracts/test/SkaleVerifierMock.sol#84)
SkaleVerifierMock.verify(IFieldOperations.Fp2Point,bytes32,uint256,uint256,uint256,IFieldOperations.G2Point) (contracts/test/SkaleVerifierMock.sol#57-99) uses a Boolean constant improperly:
	-require(bool,string)(G1Operations.isG1Point(signature.a,newSignB) || true,Sign not in G1) (contracts/test/SkaleVerifierMock.sol#83)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#misuse-of-a-boolean-constant

MathUpgradeable.mulDiv(uint256,uint256,uint256) (@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol#55-134) performs a multiplication on the result of a division:
	- denominator = denominator / twos (@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol#101)
	- inverse = (3 * denominator) ^ 2 (@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol#116)
MathUpgradeable.mulDiv(uint256,uint256,uint256) (@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol#55-134) performs a multiplication on the result of a division:
	- denominator = denominator / twos (@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol#101)
	- inverse *= 2 - denominator * inverse (@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol#120)
MathUpgradeable.mulDiv(uint256,uint256,uint256) (@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol#55-134) performs a multiplication on the result of a division:
	- denominator = denominator / twos (@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol#101)
	- inverse *= 2 - denominator * inverse (@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol#121)
MathUpgradeable.mulDiv(uint256,uint256,uint256) (@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol#55-134) performs a multiplication on the result of a division:
	- denominator = denominator / twos (@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol#101)
	- inverse *= 2 - denominator * inverse (@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol#122)
MathUpgradeable.mulDiv(uint256,uint256,uint256) (@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol#55-134) performs a multiplication on the result of a division:
	- denominator = denominator / twos (@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol#101)
	- inverse *= 2 - denominator * inverse (@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol#123)
MathUpgradeable.mulDiv(uint256,uint256,uint256) (@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol#55-134) performs a multiplication on the result of a division:
	- denominator = denominator / twos (@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol#101)
	- inverse *= 2 - denominator * inverse (@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol#124)
MathUpgradeable.mulDiv(uint256,uint256,uint256) (@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol#55-134) performs a multiplication on the result of a division:
	- denominator = denominator / twos (@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol#101)
	- inverse *= 2 - denominator * inverse (@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol#125)
MathUpgradeable.mulDiv(uint256,uint256,uint256) (@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol#55-134) performs a multiplication on the result of a division:
	- prod0 = prod0 / twos (@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol#104)
	- result = prod0 * inverse (@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol#131)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#divide-before-multiply

IERC20TransferVoid (contracts/mainnet/DepositBoxes/DepositBoxERC20.sol#35-38) has incorrect ERC20 function interface:IERC20TransferVoid.transferFrom(address,address,uint256) (contracts/mainnet/DepositBoxes/DepositBoxERC20.sol#36)
IERC20TransferVoid (contracts/mainnet/DepositBoxes/DepositBoxERC20.sol#35-38) has incorrect ERC20 function interface:IERC20TransferVoid.transfer(address,uint256) (contracts/mainnet/DepositBoxes/DepositBoxERC20.sol#37)
ERC20TransferWithoutReturn (contracts/test/erc20/ERC20TransferWithoutReturn.sol#11-24) has incorrect ERC20 function interface:IERC20TransferWithoutReturn.transferFrom(address,address,uint256) (contracts/test/erc20/ERC20TransferWithoutReturn.sol#8)
ERC20TransferWithoutReturn (contracts/test/erc20/ERC20TransferWithoutReturn.sol#11-24) has incorrect ERC20 function interface:ERC20TransferWithoutReturn.transferFrom(address,address,uint256) (contracts/test/erc20/ERC20TransferWithoutReturn.sol#16-23)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-erc20-interface

Reentrancy in FallbackEthTester.receive() (contracts/test/FallbackEthTester.sol#55-62):
	External calls:
	- communityPool.withdrawFunds(schainName,balance) (contracts/test/FallbackEthTester.sol#59)
	State variables written after the call(s):
	- _receiveInProgress = false (contracts/test/FallbackEthTester.sol#60)
	FallbackEthTester._receiveInProgress (contracts/test/FallbackEthTester.sol#42) can be used in cross function reentrancies:
	- FallbackEthTester.receive() (contracts/test/FallbackEthTester.sol#55-62)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities-1

TokenManagerERC1155._exitBatch(SchainHash,address,address,address,uint256[],uint256[]).isMainChainToken (contracts/schain/TokenManagers/TokenManagerERC1155.sol#476) is a local variable never initialized
Nodes._publicKeyToAddress(bytes32[2]).addr (contracts/test/TestNodes.sol#119) is a local variable never initialized
TokenManagerERC20._exit(SchainHash,address,address,address,uint256).isMainChainToken (contracts/schain/TokenManagers/TokenManagerERC20.sol#323) is a local variable never initialized
TokenManagerERC20._sendERC20(SchainHash,bytes).contractOnSchain (contracts/schain/TokenManagers/TokenManagerERC20.sol#264) is a local variable never initialized
TokenManagerERC1155._exit(SchainHash,address,address,address,uint256,uint256).isMainChainToken (contracts/schain/TokenManagers/TokenManagerERC1155.sol#431) is a local variable never initialized
TokenManagerERC721WithMetadata._exit(SchainHash,address,address,address,uint256).isMainChainToken (contracts/schain/TokenManagers/TokenManagerERC721WithMetadata.sol#140) is a local variable never initialized
TokenManagerERC721._exit(SchainHash,address,address,address,uint256).isMainChainToken (contracts/schain/TokenManagers/TokenManagerERC721.sol#327) is a local variable never initialized
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#uninitialized-local-variables

AccessControlEnumerableUpgradeable._grantRole(bytes32,address) (@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol#58-61) ignores return value by _roleMembers[role].add(account) (@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol#60)
AccessControlEnumerableUpgradeable._revokeRole(bytes32,address) (@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol#66-69) ignores return value by _roleMembers[role].remove(account) (@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol#68)
DepositBoxERC1155._addERC1155ForSchain(string,address) (contracts/mainnet/DepositBoxes/DepositBoxERC1155.sol#566-572) ignores return value by _schainToERC1155[schainHash].add(erc1155OnMainnet) (contracts/mainnet/DepositBoxes/DepositBoxERC1155.sol#570)
DepositBoxERC20._addERC20ForSchain(string,address) (contracts/mainnet/DepositBoxes/DepositBoxERC20.sol#810-816) ignores return value by _schainToERC20[schainHash].add(erc20OnMainnet) (contracts/mainnet/DepositBoxes/DepositBoxERC20.sol#814)
DepositBoxERC721._addERC721ForSchain(string,address) (contracts/mainnet/DepositBoxes/DepositBoxERC721.sol#332-338) ignores return value by _schainToERC721[schainHash].add(erc721OnMainnet) (contracts/mainnet/DepositBoxes/DepositBoxERC721.sol#336)
TokenManagerERC1155._addERC1155ForSchain(SchainHash,address) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#611-616) ignores return value by _schainToERC1155[chainHash].add(erc1155OnMainChain) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#614)
TokenManagerERC20._addERC20ForSchain(SchainHash,address) (contracts/schain/TokenManagers/TokenManagerERC20.sol#433-438) ignores return value by _schainToERC20[chainHash].add(erc20OnMainChain) (contracts/schain/TokenManagers/TokenManagerERC20.sol#436)
TokenManagerERC721._addERC721ForSchain(SchainHash,address) (contracts/schain/TokenManagers/TokenManagerERC721.sol#307-312) ignores return value by _schainToERC721[chainHash].add(erc721OnMainChain) (contracts/schain/TokenManagers/TokenManagerERC721.sol#310)
TokenManagerERC721WithMetadata._sendERC721(SchainHash,bytes) (contracts/schain/TokenManagers/TokenManagerERC721WithMetadata.sol#78-125) ignores return value by contractOnSchain.setTokenURI(tokenId,tokenURI) (contracts/schain/TokenManagers/TokenManagerERC721WithMetadata.sol#120)
MessageProxyForMainnet.addReimbursedContract(string,address) (contracts/mainnet/MessageProxyForMainnet.sol#236-249) ignores return value by _reimbursedContracts[schainHash].add(reimbursedContract) (contracts/mainnet/MessageProxyForMainnet.sol#247)
MessageProxyForMainnet.postIncomingMessages(string,uint256,IMessageListener.Message[],IMessageListener.Signature) (contracts/mainnet/MessageProxyForMainnet.sol#283-329) ignores return value by communityPool.refundGasBySchainWallet(fromSchainHash,address(msg.sender),notReimbursedGas) (contracts/mainnet/MessageProxyForMainnet.sol#328)
MessageProxyForMainnet._removeReimbursedContract(SchainHash,address) (contracts/mainnet/MessageProxyForMainnet.sol#565-568) ignores return value by _reimbursedContracts[schainHash].remove(reimbursedContract) (contracts/mainnet/MessageProxyForMainnet.sol#566)
MessageProxy.registerExtraContractForAll(address) (contracts/MessageProxy.sol#191-199) ignores return value by _getRegistryContracts()[SchainHash.wrap(bytes32(0))].add(extraContract) (contracts/MessageProxy.sol#197)
MessageProxy.removeExtraContractForAll(address) (contracts/MessageProxy.sol#209-216) ignores return value by _getRegistryContracts()[SchainHash.wrap(bytes32(0))].remove(extraContract) (contracts/MessageProxy.sol#214)
MessageProxy._registerExtraContract(SchainHash,address) (contracts/MessageProxy.sol#398-413) ignores return value by _getRegistryContracts()[chainHash].add(extraContract) (contracts/MessageProxy.sol#411)
MessageProxy._removeExtraContract(SchainHash,address) (contracts/MessageProxy.sol#423-432) ignores return value by _getRegistryContracts()[chainHash].remove(extraContract) (contracts/MessageProxy.sol#430)
MessageProxyForMainnetTester.refundGasByUser(SchainHash,address,address,uint256) (contracts/test/MessageProxyForMainnetTester.sol#39-49) ignores return value by communityPool.refundGasByUser(fromSchainHash,node,user,gas) (contracts/test/MessageProxyForMainnetTester.sol#48)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#unused-return

ERC1155OnChain.constructor(string).uri (contracts/schain/tokens/ERC1155OnChain.sol#42) shadows:
	- ERC1155Upgradeable.uri(uint256) (@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol#64-66) (function)
	- IERC1155MetadataURIUpgradeable.uri(uint256) (@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol#21) (function)
RevertableERC20.constructor(string,string).name (contracts/test/erc20/RevertableERC20.sol#35) shadows:
	- ERC20Upgradeable.name() (@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol#67-69) (function)
	- IERC20MetadataUpgradeable.name() (@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol#17) (function)
RevertableERC20.constructor(string,string).symbol (contracts/test/erc20/RevertableERC20.sol#35) shadows:
	- ERC20Upgradeable.symbol() (@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol#75-77) (function)
	- IERC20MetadataUpgradeable.symbol() (@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol#22) (function)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#local-variable-shadowing

Wallets.refundGasBySchain(bytes32,address,uint256,bool).spender (contracts/test/TestWallets.sol#55) lacks a zero-check on :
		- spender.transfer(amount) (contracts/test/TestWallets.sol#67)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#missing-zero-address-validation

DepositBoxERC20._doNTransfers(DepositBoxERC20.DelayedTransfer[],uint256[],uint256) (contracts/mainnet/DepositBoxes/DepositBoxERC20.sol#725-741) has external calls inside a loop: this.doTransfer(transfer.token,transfer.receiver,transfer.amount) (contracts/mainnet/DepositBoxes/DepositBoxERC20.sol#734-739)
	Calls stack containing the loop:
		DepositBoxERC20.retrieve()
		DepositBoxERC20.retrieveFor(address)
DepositBoxERC20._doNTransfers(DepositBoxERC20.DelayedTransfer[],uint256[],uint256) (contracts/mainnet/DepositBoxes/DepositBoxERC20.sol#725-741) has external calls inside a loop: this.doTransfer(transfer.token,transfer.receiver,transfer.amount) (contracts/mainnet/DepositBoxes/DepositBoxERC20.sol#734-739)
	Calls stack containing the loop:
		DepositBoxERC20.retrieveFor(address)
Linker.connectSchain(string,address[]) (contracts/mainnet/Linker.sol#92-105) has external calls inside a loop: Twin(_mainnetContracts.at(i)).addSchainContract(schainName,schainContracts[i]) (contracts/mainnet/Linker.sol#102)
Linker.disconnectSchain(string) (contracts/mainnet/Linker.sol#148-154) has external calls inside a loop: Twin(_mainnetContracts.at(i)).removeSchainContract(schainName) (contracts/mainnet/Linker.sol#151)
Linker.hasSchain(string) (contracts/mainnet/Linker.sol#173-179) has external calls inside a loop: connected = connected && Twin(_mainnetContracts.at(i)).hasSchainContract(schainName) (contracts/mainnet/Linker.sol#177)
TokenManagerLinker.connectSchain(string) (contracts/schain/TokenManagerLinker.sol#144-155) has external calls inside a loop: tokenManagers[i].addTokenManager(schainName,address(tokenManagers[i])) (contracts/schain/TokenManagerLinker.sol#152)
TokenManagerLinker.disconnectSchain(string) (contracts/schain/TokenManagerLinker.sol#164-170) has external calls inside a loop: tokenManagers[i].removeTokenManager(schainName) (contracts/schain/TokenManagerLinker.sol#167)
TokenManagerLinker.hasSchain(string) (contracts/schain/TokenManagerLinker.sol#190-197) has external calls inside a loop: connected = connected && tokenManagers[i].hasTokenManager(schainName) (contracts/schain/TokenManagerLinker.sol#194)
MessageProxy._getGasPayer(SchainHash,IMessageListener.Message,uint256) (contracts/MessageProxy.sol#497-530) has external calls inside a loop: receiver = IGasReimbursable(message.destinationContract).gasPayer{gas: gasLimit}(schainHash,message.sender,message.data) (contracts/MessageProxy.sol#505-529)
	Calls stack containing the loop:
		MessageProxyForMainnet.postIncomingMessages(string,uint256,IMessageListener.Message[],IMessageListener.Signature)
MessageProxy._callReceiverContract(SchainHash,IMessageListener.Message,uint256) (contracts/MessageProxy.sol#456-492) has external calls inside a loop: IMessageReceiver(message.destinationContract).postMessage{gas: gasLimit}(schainHash,message.sender,message.data) (contracts/MessageProxy.sol#470-491)
	Calls stack containing the loop:
		MessageProxyForMainnet.postIncomingMessages(string,uint256,IMessageListener.Message[],IMessageListener.Signature)
MessageProxyForMainnet.postIncomingMessages(string,uint256,IMessageListener.Message[],IMessageListener.Signature) (contracts/mainnet/MessageProxyForMainnet.sol#283-329) has external calls inside a loop: notReimbursedGas += communityPool.refundGasByUser(fromSchainHash,address(msg.sender),receiver,gasTotal - gasleft()() + additionalGasPerMessage) (contracts/mainnet/MessageProxyForMainnet.sol#317-322)
MessageProxy._callReceiverContract(SchainHash,IMessageListener.Message,uint256) (contracts/MessageProxy.sol#456-492) has external calls inside a loop: IMessageReceiver(message.destinationContract).postMessage{gas: gasLimit}(schainHash,message.sender,message.data) (contracts/MessageProxy.sol#470-491)
	Calls stack containing the loop:
		MessageProxyForSchain.postIncomingMessages(string,uint256,IMessageListener.Message[],IMessageListener.Signature)
SchainsInternal.addNodesToSchainsGroups(bytes32,uint256[]) (contracts/test/TestSchainsInternal.sol#94-101) has external calls inside a loop: nodeAddress = nodesContract.getNodeAddress(nodes[i]) (contracts/test/TestSchainsInternal.sol#98)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation/#calls-inside-a-loop

Reentrancy in FallbackEthTester.getMyEth() (contracts/test/FallbackEthTester.sol#72-76):
	External calls:
	- depositBoxEth.getMyEth() (contracts/test/FallbackEthTester.sol#74)
	State variables written after the call(s):
	- _getMyEthInProgress = false (contracts/test/FallbackEthTester.sol#75)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities-2

Reentrancy in MessageProxy._callReceiverContract(SchainHash,IMessageListener.Message,uint256) (contracts/MessageProxy.sol#456-492):
	External calls:
	- IMessageReceiver(message.destinationContract).postMessage{gas: gasLimit}(schainHash,message.sender,message.data) (contracts/MessageProxy.sol#470-491)
	Event emitted after the call(s):
	- PostMessageError(counter,_getSlice(bytes(reason),REVERT_REASON_LENGTH)) (contracts/MessageProxy.sol#477-480)
	- PostMessageError(counter,abi.encodePacked(errorCode)) (contracts/MessageProxy.sol#482-485)
	- PostMessageError(counter,_getSlice(revertData,REVERT_REASON_LENGTH)) (contracts/MessageProxy.sol#487-490)
Reentrancy in DepositBoxERC20._doNTransfers(DepositBoxERC20.DelayedTransfer[],uint256[],uint256) (contracts/mainnet/DepositBoxes/DepositBoxERC20.sol#725-741):
	External calls:
	- this.doTransfer(transfer.token,transfer.receiver,transfer.amount) (contracts/mainnet/DepositBoxes/DepositBoxERC20.sol#734-739)
	Event emitted after the call(s):
	- TransferSkipped(transfersIds[i]) (contracts/mainnet/DepositBoxes/DepositBoxERC20.sol#738)
	- TransferSucceeded(transfersIds[i]) (contracts/mainnet/DepositBoxes/DepositBoxERC20.sol#735)
Reentrancy in MessageProxy._getGasPayer(SchainHash,IMessageListener.Message,uint256) (contracts/MessageProxy.sol#497-530):
	External calls:
	- receiver = IGasReimbursable(message.destinationContract).gasPayer{gas: gasLimit}(schainHash,message.sender,message.data) (contracts/MessageProxy.sol#505-529)
	Event emitted after the call(s):
	- PostMessageError(counter,_getSlice(bytes(reason),REVERT_REASON_LENGTH)) (contracts/MessageProxy.sol#512-515)
	- PostMessageError(counter,abi.encodePacked(errorCode)) (contracts/MessageProxy.sol#518-521)
	- PostMessageError(counter,_getSlice(revertData,REVERT_REASON_LENGTH)) (contracts/MessageProxy.sol#524-527)
Reentrancy in TokenManagerERC1155._sendERC1155(SchainHash,bytes) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#315-365):
	External calls:
	- IERC1155Upgradeable(token).safeTransferFrom(address(this),receiver,id,amount,) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#352)
	- contractOnSchain.mint(receiver,id,amount,) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#354)
	Event emitted after the call(s):
	- ERC1155TokenReceived(fromChainHash,token,address(contractOnSchain),_asSingletonArray(id),_asSingletonArray(amount)) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#356-362)
Reentrancy in TokenManagerERC1155._sendERC1155Batch(SchainHash,bytes) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#373-416):
	External calls:
	- IERC1155Upgradeable(token).safeBatchTransferFrom(address(this),receiver,ids,amounts,) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#409)
	- contractOnSchain.mintBatch(receiver,ids,amounts,) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#411)
	Event emitted after the call(s):
	- ERC1155TokenReceived(fromChainHash,token,address(contractOnSchain),ids,amounts) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#413)
Reentrancy in TokenManagerERC20._sendERC20(SchainHash,bytes) (contracts/schain/TokenManagers/TokenManagerERC20.sol#261-309):
	External calls:
	- contractOnSchain.mint(receiver,amount) (contracts/schain/TokenManagers/TokenManagerERC20.sol#296)
	- require(bool,string)(ERC20Upgradeable(token).transfer(receiver,amount),Transfer was failed) (contracts/schain/TokenManagers/TokenManagerERC20.sol#301-304)
	Event emitted after the call(s):
	- ERC20TokenReceived(fromChainHash,token,address(contractOnSchain),amount) (contracts/schain/TokenManagers/TokenManagerERC20.sol#306)
Reentrancy in TokenManagerERC721._sendERC721(SchainHash,bytes) (contracts/schain/TokenManagers/TokenManagerERC721.sol#212-254):
	External calls:
	- IERC721Upgradeable(token).transferFrom(address(this),receiver,tokenId) (contracts/schain/TokenManagers/TokenManagerERC721.sol#247)
	- contractOnSchain.mint(receiver,tokenId) (contracts/schain/TokenManagers/TokenManagerERC721.sol#249)
	Event emitted after the call(s):
	- ERC721TokenReceived(fromChainHash,token,address(contractOnSchain),tokenId) (contracts/schain/TokenManagers/TokenManagerERC721.sol#251)
Reentrancy in TokenManagerERC721WithMetadata._sendERC721(SchainHash,bytes) (contracts/schain/TokenManagers/TokenManagerERC721WithMetadata.sol#78-125):
	External calls:
	- IERC721Upgradeable(token).transferFrom(address(this),receiver,tokenId) (contracts/schain/TokenManagers/TokenManagerERC721WithMetadata.sol#117)
	- contractOnSchain.mint(receiver,tokenId) (contracts/schain/TokenManagers/TokenManagerERC721WithMetadata.sol#119)
	- contractOnSchain.setTokenURI(tokenId,tokenURI) (contracts/schain/TokenManagers/TokenManagerERC721WithMetadata.sol#120)
	Event emitted after the call(s):
	- ERC721TokenReceived(fromChainHash,token,address(contractOnSchain),tokenId) (contracts/schain/TokenManagers/TokenManagerERC721WithMetadata.sol#122)
Reentrancy in TokenManagerERC1155.exitToMainERC1155(address,uint256,uint256) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#109-119):
	External calls:
	- communityLocker.checkAllowedToSendMessage(MAINNET_HASH,msg.sender) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#117)
	- _exit(MAINNET_HASH,depositBox,contractOnMainnet,msg.sender,id,amount) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#118)
		- contractOnSchain.safeTransferFrom(msg.sender,address(this),id,amount,) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#456)
		- contractOnSchain.burn(msg.sender,id,amount) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#458)
		- messageProxy.postOutgoingMessage(chainHash,messageReceiver,data) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#460)
	Event emitted after the call(s):
	- ERC1155TokenAdded(chainHash,erc1155OnMainChain,address(0)) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#615)
		- _exit(MAINNET_HASH,depositBox,contractOnMainnet,msg.sender,id,amount) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#118)
	- ERC1155TokenReady(chainHash,erc1155OnMainChain,_asSingletonArray(id),_asSingletonArray(amount)) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#564)
		- _exit(MAINNET_HASH,depositBox,contractOnMainnet,msg.sender,id,amount) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#118)
Reentrancy in TokenManagerERC1155.exitToMainERC1155Batch(address,uint256[],uint256[]) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#126-136):
	External calls:
	- communityLocker.checkAllowedToSendMessage(MAINNET_HASH,msg.sender) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#134)
	- _exitBatch(MAINNET_HASH,depositBox,contractOnMainnet,msg.sender,ids,amounts) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#135)
		- contractOnSchain.safeBatchTransferFrom(msg.sender,address(this),ids,amounts,) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#496)
		- contractOnSchain.burnBatch(msg.sender,ids,amounts) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#498)
		- messageProxy.postOutgoingMessage(chainHash,messageReceiver,data) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#500)
	Event emitted after the call(s):
	- ERC1155TokenAdded(chainHash,erc1155OnMainChain,address(0)) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#615)
		- _exitBatch(MAINNET_HASH,depositBox,contractOnMainnet,msg.sender,ids,amounts) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#135)
	- ERC1155TokenReady(chainHash,erc1155OnMainChain,ids,amounts) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#599)
		- _exitBatch(MAINNET_HASH,depositBox,contractOnMainnet,msg.sender,ids,amounts) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#135)
Reentrancy in TokenManagerERC20.exitToMainERC20(address,uint256) (contracts/schain/TokenManagers/TokenManagerERC20.sol#105-114):
	External calls:
	- communityLocker.checkAllowedToSendMessage(MAINNET_HASH,msg.sender) (contracts/schain/TokenManagers/TokenManagerERC20.sol#112)
	- _exit(MAINNET_HASH,depositBox,contractOnMainnet,msg.sender,amount) (contracts/schain/TokenManagers/TokenManagerERC20.sol#113)
		- require(bool,string)(contractOnSchain.transferFrom(msg.sender,address(this),amount),Transfer was failed) (contracts/schain/TokenManagers/TokenManagerERC20.sol#349-352)
		- require(bool,string)(contractOnSchain.transferFrom(msg.sender,address(this),amount),Transfer was failed) (contracts/schain/TokenManagers/TokenManagerERC20.sol#354-357)
		- contractOnSchain.burn(amount) (contracts/schain/TokenManagers/TokenManagerERC20.sol#358)
		- messageProxy.postOutgoingMessage(chainHash,messageReceiver,data) (contracts/schain/TokenManagers/TokenManagerERC20.sol#360-364)
	Event emitted after the call(s):
	- ERC20TokenAdded(chainHash,erc20OnMainChain,address(0)) (contracts/schain/TokenManagers/TokenManagerERC20.sol#437)
		- _exit(MAINNET_HASH,depositBox,contractOnMainnet,msg.sender,amount) (contracts/schain/TokenManagers/TokenManagerERC20.sol#113)
	- ERC20TokenReady(chainHash,erc20OnMainChain,amount) (contracts/schain/TokenManagers/TokenManagerERC20.sol#421)
		- _exit(MAINNET_HASH,depositBox,contractOnMainnet,msg.sender,amount) (contracts/schain/TokenManagers/TokenManagerERC20.sol#113)
Reentrancy in TokenManagerERC721.exitToMainERC721(address,uint256) (contracts/schain/TokenManagers/TokenManagerERC721.sol#97-106):
	External calls:
	- communityLocker.checkAllowedToSendMessage(MAINNET_HASH,msg.sender) (contracts/schain/TokenManagers/TokenManagerERC721.sol#104)
	- _exit(MAINNET_HASH,depositBox,contractOnMainnet,msg.sender,tokenId) (contracts/schain/TokenManagers/TokenManagerERC721.sol#105)
		- contractOnSchain.transferFrom(msg.sender,address(this),tokenId) (contracts/schain/TokenManagers/TokenManagerERC721.sol#346)
		- contractOnSchain.transferFrom(msg.sender,address(this),tokenId) (contracts/schain/TokenManagers/TokenManagerERC721.sol#348)
		- contractOnSchain.burn(tokenId) (contracts/schain/TokenManagers/TokenManagerERC721.sol#349)
		- messageProxy.postOutgoingMessage(chainHash,messageReceiver,data) (contracts/schain/TokenManagers/TokenManagerERC721.sol#351)
	Event emitted after the call(s):
	- ERC721TokenAdded(chainHash,erc721OnMainChain,address(0)) (contracts/schain/TokenManagers/TokenManagerERC721.sol#311)
		- _exit(MAINNET_HASH,depositBox,contractOnMainnet,msg.sender,tokenId) (contracts/schain/TokenManagers/TokenManagerERC721.sol#105)
	- ERC721TokenReady(chainHash,erc721OnMainChain,tokenId) (contracts/schain/TokenManagers/TokenManagerERC721.sol#295)
		- _exit(MAINNET_HASH,depositBox,contractOnMainnet,msg.sender,tokenId) (contracts/schain/TokenManagers/TokenManagerERC721.sol#105)
Reentrancy in MessageProxyForMainnet.postIncomingMessages(string,uint256,IMessageListener.Message[],IMessageListener.Signature) (contracts/mainnet/MessageProxyForMainnet.sol#283-329):
	External calls:
	- receiver = _getGasPayer(fromSchainHash,messages[i],startingCounter + i) (contracts/mainnet/MessageProxyForMainnet.sol#315)
		- receiver = IGasReimbursable(message.destinationContract).gasPayer{gas: gasLimit}(schainHash,message.sender,message.data) (contracts/MessageProxy.sol#505-529)
	- _callReceiverContract(fromSchainHash,messages[i],startingCounter + i) (contracts/mainnet/MessageProxyForMainnet.sol#316)
		- IMessageReceiver(message.destinationContract).postMessage{gas: gasLimit}(schainHash,message.sender,message.data) (contracts/MessageProxy.sol#470-491)
	- notReimbursedGas += communityPool.refundGasByUser(fromSchainHash,address(msg.sender),receiver,gasTotal - gasleft()() + additionalGasPerMessage) (contracts/mainnet/MessageProxyForMainnet.sol#317-322)
	- _callReceiverContract(fromSchainHash,messages[i],startingCounter + i) (contracts/mainnet/MessageProxyForMainnet.sol#324)
		- IMessageReceiver(message.destinationContract).postMessage{gas: gasLimit}(schainHash,message.sender,message.data) (contracts/MessageProxy.sol#470-491)
	Event emitted after the call(s):
	- PostMessageError(counter,Destination contract is not a contract) (contracts/MessageProxy.sol#464-467)
		- _callReceiverContract(fromSchainHash,messages[i],startingCounter + i) (contracts/mainnet/MessageProxyForMainnet.sol#324)
	- PostMessageError(counter,Destination contract is not a contract) (contracts/MessageProxy.sol#464-467)
		- _callReceiverContract(fromSchainHash,messages[i],startingCounter + i) (contracts/mainnet/MessageProxyForMainnet.sol#316)
	- PostMessageError(counter,_getSlice(bytes(reason),REVERT_REASON_LENGTH)) (contracts/MessageProxy.sol#512-515)
		- receiver = _getGasPayer(fromSchainHash,messages[i],startingCounter + i) (contracts/mainnet/MessageProxyForMainnet.sol#315)
	- PostMessageError(counter,abi.encodePacked(errorCode)) (contracts/MessageProxy.sol#518-521)
		- receiver = _getGasPayer(fromSchainHash,messages[i],startingCounter + i) (contracts/mainnet/MessageProxyForMainnet.sol#315)
	- PostMessageError(counter,_getSlice(bytes(reason),REVERT_REASON_LENGTH)) (contracts/MessageProxy.sol#477-480)
		- _callReceiverContract(fromSchainHash,messages[i],startingCounter + i) (contracts/mainnet/MessageProxyForMainnet.sol#316)
	- PostMessageError(counter,_getSlice(bytes(reason),REVERT_REASON_LENGTH)) (contracts/MessageProxy.sol#477-480)
		- _callReceiverContract(fromSchainHash,messages[i],startingCounter + i) (contracts/mainnet/MessageProxyForMainnet.sol#324)
	- PostMessageError(counter,abi.encodePacked(errorCode)) (contracts/MessageProxy.sol#482-485)
		- _callReceiverContract(fromSchainHash,messages[i],startingCounter + i) (contracts/mainnet/MessageProxyForMainnet.sol#324)
	- PostMessageError(counter,_getSlice(revertData,REVERT_REASON_LENGTH)) (contracts/MessageProxy.sol#524-527)
		- receiver = _getGasPayer(fromSchainHash,messages[i],startingCounter + i) (contracts/mainnet/MessageProxyForMainnet.sol#315)
	- PostMessageError(counter,abi.encodePacked(errorCode)) (contracts/MessageProxy.sol#482-485)
		- _callReceiverContract(fromSchainHash,messages[i],startingCounter + i) (contracts/mainnet/MessageProxyForMainnet.sol#316)
	- PostMessageError(counter,_getSlice(revertData,REVERT_REASON_LENGTH)) (contracts/MessageProxy.sol#487-490)
		- _callReceiverContract(fromSchainHash,messages[i],startingCounter + i) (contracts/mainnet/MessageProxyForMainnet.sol#316)
	- PostMessageError(counter,_getSlice(revertData,REVERT_REASON_LENGTH)) (contracts/MessageProxy.sol#487-490)
		- _callReceiverContract(fromSchainHash,messages[i],startingCounter + i) (contracts/mainnet/MessageProxyForMainnet.sol#324)
Reentrancy in TokenManagerERC1155.transferToSchainERC1155(string,address,uint256,uint256) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#144-157):
	External calls:
	- communityLocker.checkAllowedToSendMessage(targetSchainHash,msg.sender) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#155)
	- _exit(targetSchainHash,tokenManagers[targetSchainHash],contractOnMainnet,msg.sender,id,amount) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#156)
		- contractOnSchain.safeTransferFrom(msg.sender,address(this),id,amount,) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#456)
		- contractOnSchain.burn(msg.sender,id,amount) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#458)
		- messageProxy.postOutgoingMessage(chainHash,messageReceiver,data) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#460)
	Event emitted after the call(s):
	- ERC1155TokenAdded(chainHash,erc1155OnMainChain,address(0)) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#615)
		- _exit(targetSchainHash,tokenManagers[targetSchainHash],contractOnMainnet,msg.sender,id,amount) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#156)
	- ERC1155TokenReady(chainHash,erc1155OnMainChain,_asSingletonArray(id),_asSingletonArray(amount)) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#564)
		- _exit(targetSchainHash,tokenManagers[targetSchainHash],contractOnMainnet,msg.sender,id,amount) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#156)
Reentrancy in TokenManagerERC1155.transferToSchainERC1155Batch(string,address,uint256[],uint256[]) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#165-178):
	External calls:
	- communityLocker.checkAllowedToSendMessage(targetSchainHash,msg.sender) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#176)
	- _exitBatch(targetSchainHash,tokenManagers[targetSchainHash],contractOnMainnet,msg.sender,ids,amounts) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#177)
		- contractOnSchain.safeBatchTransferFrom(msg.sender,address(this),ids,amounts,) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#496)
		- contractOnSchain.burnBatch(msg.sender,ids,amounts) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#498)
		- messageProxy.postOutgoingMessage(chainHash,messageReceiver,data) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#500)
	Event emitted after the call(s):
	- ERC1155TokenAdded(chainHash,erc1155OnMainChain,address(0)) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#615)
		- _exitBatch(targetSchainHash,tokenManagers[targetSchainHash],contractOnMainnet,msg.sender,ids,amounts) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#177)
	- ERC1155TokenReady(chainHash,erc1155OnMainChain,ids,amounts) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#599)
		- _exitBatch(targetSchainHash,tokenManagers[targetSchainHash],contractOnMainnet,msg.sender,ids,amounts) (contracts/schain/TokenManagers/TokenManagerERC1155.sol#177)
Reentrancy in TokenManagerERC721.transferToSchainERC721(string,address,uint256) (contracts/schain/TokenManagers/TokenManagerERC721.sol#114-126):
	External calls:
	- communityLocker.checkAllowedToSendMessage(targetSchainHash,msg.sender) (contracts/schain/TokenManagers/TokenManagerERC721.sol#124)
	- _exit(targetSchainHash,tokenManagers[targetSchainHash],contractOnMainnet,msg.sender,tokenId) (contracts/schain/TokenManagers/TokenManagerERC721.sol#125)
		- contractOnSchain.transferFrom(msg.sender,address(this),tokenId) (contracts/schain/TokenManagers/TokenManagerERC721.sol#346)
		- contractOnSchain.transferFrom(msg.sender,address(this),tokenId) (contracts/schain/TokenManagers/TokenManagerERC721.sol#348)
		- contractOnSchain.burn(tokenId) (contracts/schain/TokenManagers/TokenManagerERC721.sol#349)
		- messageProxy.postOutgoingMessage(chainHash,messageReceiver,data) (contracts/schain/TokenManagers/TokenManagerERC721.sol#351)
	Event emitted after the call(s):
	- ERC721TokenAdded(chainHash,erc721OnMainChain,address(0)) (contracts/schain/TokenManagers/TokenManagerERC721.sol#311)
		- _exit(targetSchainHash,tokenManagers[targetSchainHash],contractOnMainnet,msg.sender,tokenId) (contracts/schain/TokenManagers/TokenManagerERC721.sol#125)
	- ERC721TokenReady(chainHash,erc721OnMainChain,tokenId) (contracts/schain/TokenManagers/TokenManagerERC721.sol#295)
		- _exit(targetSchainHash,tokenManagers[targetSchainHash],contractOnMainnet,msg.sender,tokenId) (contracts/schain/TokenManagers/TokenManagerERC721.sol#125)
Reentrancy in TokenManagerERC20.transferToSchainHashERC20Direct(SchainHash,address,uint256,address) (contracts/schain/TokenManagers/TokenManagerERC20.sol#239-251):
	External calls:
	- communityLocker.checkAllowedToSendMessage(targetSchainHash,msg.sender) (contracts/schain/TokenManagers/TokenManagerERC20.sol#249)
	- _exit(targetSchainHash,tokenManagers[targetSchainHash],contractOnMainnet,receiver,amount) (contracts/schain/TokenManagers/TokenManagerERC20.sol#250)
		- require(bool,string)(contractOnSchain.transferFrom(msg.sender,address(this),amount),Transfer was failed) (contracts/schain/TokenManagers/TokenManagerERC20.sol#349-352)
		- require(bool,string)(contractOnSchain.transferFrom(msg.sender,address(this),amount),Transfer was failed) (contracts/schain/TokenManagers/TokenManagerERC20.sol#354-357)
		- contractOnSchain.burn(amount) (contracts/schain/TokenManagers/TokenManagerERC20.sol#358)
		- messageProxy.postOutgoingMessage(chainHash,messageReceiver,data) (contracts/schain/TokenManagers/TokenManagerERC20.sol#360-364)
	Event emitted after the call(s):
	- ERC20TokenAdded(chainHash,erc20OnMainChain,address(0)) (contracts/schain/TokenManagers/TokenManagerERC20.sol#437)
		- _exit(targetSchainHash,tokenManagers[targetSchainHash],contractOnMainnet,receiver,amount) (contracts/schain/TokenManagers/TokenManagerERC20.sol#250)
	- ERC20TokenReady(chainHash,erc20OnMainChain,amount) (contracts/schain/TokenManagers/TokenManagerERC20.sol#421)
		- _exit(targetSchainHash,tokenManagers[targetSchainHash],contractOnMainnet,receiver,amount) (contracts/schain/TokenManagers/TokenManagerERC20.sol#250)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities-3

DepositBoxERC20.escalate(uint256) (contracts/mainnet/DepositBoxes/DepositBoxERC20.sol#392-405) uses timestamp for comparisons
	Dangerous comparisons:
	- require(bool,string)(hasRole(ARBITER_ROLE,msg.sender) || isSchainOwner(msg.sender,schainHash),Not enough permissions to request escalation) (contracts/mainnet/DepositBoxes/DepositBoxERC20.sol#394-397)
	- require(bool,string)(delayedTransfers[transferId].status == DelayedTransferStatus.DELAYED,The transfer has to be delayed) (contracts/mainnet/DepositBoxes/DepositBoxERC20.sol#398)
DepositBoxERC20.validateTransfer(uint256) (contracts/mainnet/DepositBoxes/DepositBoxERC20.sol#415-427) uses timestamp for comparisons
	Dangerous comparisons:
	- require(bool,string)(transfer.status == DelayedTransferStatus.ARBITRAGE,Arbitrage has to be active) (contracts/mainnet/DepositBoxes/DepositBoxERC20.sol#423)
DepositBoxERC20.rejectTransfer(uint256) (contracts/mainnet/DepositBoxes/DepositBoxERC20.sol#437-450) uses timestamp for comparisons
	Dangerous comparisons:
	- require(bool,string)(transfer.status == DelayedTransferStatus.ARBITRAGE,Arbitrage has to be active) (contracts/mainnet/DepositBoxes/DepositBoxERC20.sol#445)
DepositBoxERC20.retrieveFor(address) (contracts/mainnet/DepositBoxes/DepositBoxERC20.sol#609-652) uses timestamp for comparisons
	Dangerous comparisons:
	- transfer.status != DelayedTransferStatus.COMPLETED (contracts/mainnet/DepositBoxes/DepositBoxERC20.sol#622)
	- block.timestamp < transfer.untilTimestamp (contracts/mainnet/DepositBoxes/DepositBoxERC20.sol#623)
	- transfer.status == DelayedTransferStatus.DELAYED (contracts/mainnet/DepositBoxes/DepositBoxERC20.sol#627)
DepositBoxERC20._addToDelayedQueueWithPriority(DoubleEndedQueueUpgradeable.Bytes32Deque,uint256,uint256,uint256) (contracts/mainnet/DepositBoxes/DepositBoxERC20.sol#837-856) uses timestamp for comparisons
	Dangerous comparisons:
	- delayedTransfers[uint256(queue.back())].untilTimestamp <= until (contracts/mainnet/DepositBoxes/DepositBoxERC20.sol#848)
CommunityLocker.setGasPrice(uint256,uint256,IMessageListener.Signature) (contracts/schain/CommunityLocker.sol#252-274) uses timestamp for comparisons
	Dangerous comparisons:
	- require(bool,string)(timestamp <= block.timestamp,Timestamp should not be in the future) (contracts/schain/CommunityLocker.sol#261)
Nodes._checkNodeIndex(uint256) (contracts/test/TestNodes.sol#113-115) uses timestamp for comparisons
	Dangerous comparisons:
	- require(bool,string)(nodeIndex < nodes.length,Node with such index does not exist) (contracts/test/TestNodes.sol#114)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#block-timestamp

ERC721Upgradeable._checkOnERC721Received(address,address,uint256,bytes) (@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol#404-426) uses assembly
	- INLINE ASM (@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol#418-420)
AddressUpgradeable._revert(bytes,string) (@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol#231-243) uses assembly
	- INLINE ASM (@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol#236-239)
StringsUpgradeable.toString(uint256) (@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol#19-39) uses assembly
	- INLINE ASM (@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol#25-27)
	- INLINE ASM (@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol#31-33)
MathUpgradeable.mulDiv(uint256,uint256,uint256) (@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol#55-134) uses assembly
	- INLINE ASM (@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol#62-66)
	- INLINE ASM (@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol#85-92)
	- INLINE ASM (@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol#99-108)
EnumerableSetUpgradeable.values(EnumerableSetUpgradeable.Bytes32Set) (@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol#219-229) uses assembly
	- INLINE ASM (@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol#224-226)
EnumerableSetUpgradeable.values(EnumerableSetUpgradeable.AddressSet) (@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol#293-303) uses assembly
	- INLINE ASM (@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol#298-300)
EnumerableSetUpgradeable.values(EnumerableSetUpgradeable.UintSet) (@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol#367-377) uses assembly
	- INLINE ASM (@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol#372-374)
KeyStorage._getConfigVariableUint256(string) (contracts/schain/KeyStorage.sol#73-95) uses assembly
	- INLINE ASM (contracts/schain/KeyStorage.sol#84-93)
KeyStorage._getCurrentBLSPublicKey() (contracts/schain/KeyStorage.sol#100-125) uses assembly
	- INLINE ASM (contracts/schain/KeyStorage.sol#112-119)
Precompiled.bn256Pairing(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256) (contracts/schain/bls/Precompiled.sol#40-76) uses assembly
	- INLINE ASM (contracts/schain/bls/Precompiled.sol#71-73)
ConfigReader.getConfigVariableUint256(string) (contracts/test/ConfigReader.sol#35-57) uses assembly
	- INLINE ASM (contracts/test/ConfigReader.sol#46-55)
ConfigReader.getConfigVariableAddress(string) (contracts/test/ConfigReader.sol#59-81) uses assembly
	- INLINE ASM (contracts/test/ConfigReader.sol#70-79)
ConfigReader.getConfigVariableString(string) (contracts/test/ConfigReader.sol#83-105) uses assembly
	- INLINE ASM (contracts/test/ConfigReader.sol#88-103)
ConfigReader.getConfigPermissionFlag(address,string) (contracts/test/ConfigReader.sol#107-133) uses assembly
	- INLINE ASM (contracts/test/ConfigReader.sol#120-131)
Logger.logTextMessage(uint256,string) (contracts/test/Logger.sol#31-54) uses assembly
	- INLINE ASM (contracts/test/Logger.sol#37-53)
PrecompiledMock.bigModExp(uint256,uint256,uint256) (contracts/test/PrecompiledMock.sol#27-43) uses assembly
	- INLINE ASM (contracts/test/PrecompiledMock.sol#38-40)
PrecompiledMock.bn256ScalarMul(uint256,uint256,uint256) (contracts/test/PrecompiledMock.sol#45-58) uses assembly
	- INLINE ASM (contracts/test/PrecompiledMock.sol#53-55)
PrecompiledMock.bn256Pairing(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256) (contracts/test/PrecompiledMock.sol#60-96) uses assembly
	- INLINE ASM (contracts/test/PrecompiledMock.sol#91-93)
SafeMock.multiSend(bytes) (contracts/test/SafeMock.sol#78-111) uses assembly
	- INLINE ASM (contracts/test/SafeMock.sol#81-110)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#assembly-usage

7 different versions of Solidity are used:
	- Version constraint ^0.8.0 is used by:
		-^0.8.0 (@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol#4)
		-^0.8.0 (@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol#4)
		-^0.8.0 (@openzeppelin/contracts-upgradeable/access/IAccessControlEnumerableUpgradeable.sol#4)
		-^0.8.0 (@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol#4)
		-^0.8.0 (@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol#4)
		-^0.8.0 (@openzeppelin/contracts-upgradeable/interfaces/IERC165Upgradeable.sol#4)
		-^0.8.0 (@openzeppelin/contracts-upgradeable/interfaces/IERC4906Upgradeable.sol#4)
		-^0.8.0 (@openzeppelin/contracts-upgradeable/interfaces/IERC721Upgradeable.sol#4)
		-^0.8.0 (@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol#4)
		-^0.8.0 (@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol#4)
		-^0.8.0 (@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol#4)
		-^0.8.0 (@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol#4)
		-^0.8.0 (@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol#4)
		-^0.8.0 (@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol#4)
		-^0.8.0 (@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol#4)
		-^0.8.0 (@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol#4)
		-^0.8.0 (@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol#4)
		-^0.8.0 (@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol#4)
		-^0.8.0 (@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20PermitUpgradeable.sol#4)
		-^0.8.0 (@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol#4)
		-^0.8.0 (@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol#4)
		-^0.8.0 (@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol#4)
		-^0.8.0 (@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol#4)
		-^0.8.0 (@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol#4)
		-^0.8.0 (@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol#4)
		-^0.8.0 (@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol#4)
		-^0.8.0 (@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol#4)
		-^0.8.0 (@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol#4)
		-^0.8.0 (@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol#4)
		-^0.8.0 (@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol#4)
		-^0.8.0 (@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol#4)
		-^0.8.0 (@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol#5)
		-^0.8.0 (@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol#4)
		-^0.8.0 (@openzeppelin/contracts-upgradeable/utils/math/SignedMathUpgradeable.sol#4)
		-^0.8.0 (@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol#5)
		-^0.8.0 (@skalenetwork/etherbase-interfaces/IEtherbase.sol#23)
		-^0.8.0 (@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol#23)
	- Version constraint ^0.8.2 is used by:
		-^0.8.2 (@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol#4)
	- Version constraint ^0.8.1 is used by:
		-^0.8.1 (@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol#4)
	- Version constraint ^0.8.4 is used by:
		-^0.8.4 (@openzeppelin/contracts-upgradeable/utils/structs/DoubleEndedQueueUpgradeable.sol#3)
	- Version constraint >=0.8.19<0.9.0 is used by:
		->=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/DomainTypes.sol#21)
		->=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/IGasReimbursable.sol#22)
		->=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/IMessageListener.sol#22)
		->=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/IMessageProxy.sol#22)
		->=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/IMessageReceiver.sol#22)
		->=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataMainnet.sol#22)
		->=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataSchain.sol#22)
		->=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC1155.sol#22)
		->=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC20.sol#22)
		->=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC721.sol#22)
		->=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol#22)
		->=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol#22)
		->=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/mainnet/IDepositBox.sol#22)
		->=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/mainnet/ILinker.sol#22)
		->=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/mainnet/IMessageProxyForMainnet.sol#22)
		->=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/mainnet/ISkaleManagerClient.sol#22)
		->=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/mainnet/ITwin.sol#22)
		->=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol#22)
		->=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/schain/IKeyStorage.sol#22)
		->=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/schain/IMessageProxyForSchain.sol#22)
		->=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/schain/ITokenManager.sol#22)
		->=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/schain/ITokenManagerLinker.sol#22)
		->=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenContractManager.sol#22)
		->=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC1155.sol#22)
		->=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC20.sol#22)
		->=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC721.sol#22)
		->=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerEth.sol#22)
		->=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/schain/bls/IFieldOperations.sol#22)
		->=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/schain/tokens/IERC1155OnChain.sol#22)
		->=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/schain/tokens/IERC20OnChain.sol#22)
		->=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/schain/tokens/IERC721OnChain.sol#22)
		->=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/schain/tokens/IEthErc20.sol#22)
	- Version constraint >=0.6.10<0.9.0 is used by:
		->=0.6.10<0.9.0 (@skalenetwork/skale-manager-interfaces/IContractManager.sol#22)
		->=0.6.10<0.9.0 (@skalenetwork/skale-manager-interfaces/INodes.sol#22)
		->=0.6.10<0.9.0 (@skalenetwork/skale-manager-interfaces/ISchains.sol#22)
		->=0.6.10<0.9.0 (@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol#22)
		->=0.6.10<0.9.0 (@skalenetwork/skale-manager-interfaces/IWallets.sol#22)
		->=0.6.10<0.9.0 (@skalenetwork/skale-manager-interfaces/utils/IRandom.sol#22)
	- Version constraint 0.8.27 is used by:
		-0.8.27 (contracts/MessageProxy.sol#22)
		-0.8.27 (contracts/Messages.sol#22)
		-0.8.27 (contracts/extensions/ERC721ReferenceMintAndMetadataMainnet.sol#22)
		-0.8.27 (contracts/extensions/ERC721ReferenceMintAndMetadataSchain.sol#22)
		-0.8.27 (contracts/extensions/interfaces/MessageProxyClient.sol#22)
		-0.8.27 (contracts/extensions/interfaces/MessageReceiver.sol#22)
		-0.8.27 (contracts/extensions/interfaces/MessageSender.sol#22)
		-0.8.27 (contracts/mainnet/CommunityPool.sol#24)
		-0.8.27 (contracts/mainnet/DepositBox.sol#23)
		-0.8.27 (contracts/mainnet/DepositBoxes/DepositBoxERC1155.sol#22)
		-0.8.27 (contracts/mainnet/DepositBoxes/DepositBoxERC20.sol#22)
		-0.8.27 (contracts/mainnet/DepositBoxes/DepositBoxERC721.sol#22)
		-0.8.27 (contracts/mainnet/DepositBoxes/DepositBoxERC721WithMetadata.sol#22)
		-0.8.27 (contracts/mainnet/DepositBoxes/DepositBoxEth.sol#22)
		-0.8.27 (contracts/mainnet/Linker.sol#22)
		-0.8.27 (contracts/mainnet/MessageProxyForMainnet.sol#22)
		-0.8.27 (contracts/mainnet/SkaleManagerClient.sol#22)
		-0.8.27 (contracts/mainnet/Twin.sol#24)
		-0.8.27 (contracts/schain/CommunityLocker.sol#24)
		-0.8.27 (contracts/schain/DefaultAddresses.sol#22)
		-0.8.27 (contracts/schain/KeyStorage.sol#22)
		-0.8.27 (contracts/schain/MessageProxyForSchain.sol#22)
		-0.8.27 (contracts/schain/TokenManager.sol#22)
		-0.8.27 (contracts/schain/TokenManagerLinker.sol#22)
		-0.8.27 (contracts/schain/TokenManagers/TokenManagerERC1155.sol#22)
		-0.8.27 (contracts/schain/TokenManagers/TokenManagerERC20.sol#22)
		-0.8.27 (contracts/schain/TokenManagers/TokenManagerERC721.sol#22)
		-0.8.27 (contracts/schain/TokenManagers/TokenManagerERC721WithMetadata.sol#22)
		-0.8.27 (contracts/schain/TokenManagers/TokenManagerEth.sol#22)
		-0.8.27 (contracts/schain/bls/FieldOperations.sol#23)
		-0.8.27 (contracts/schain/bls/Precompiled.sol#22)
		-0.8.27 (contracts/schain/bls/SkaleVerifier.sol#22)
		-0.8.27 (contracts/schain/tokens/ERC1155OnChain.sol#23)
		-0.8.27 (contracts/schain/tokens/ERC20OnChain.sol#23)
		-0.8.27 (contracts/schain/tokens/ERC721OnChain.sol#23)
		-0.8.27 (contracts/schain/tokens/EthErc20.sol#22)
		-0.8.27 (contracts/test/ConfigReader.sol#23)
		-0.8.27 (contracts/test/EtherbaseMock.sol#22)
		-0.8.27 (contracts/test/FallbackEthTester.sol#23)
		-0.8.27 (contracts/test/KeyStorageMock.sol#22)
		-0.8.27 (contracts/test/Logger.sol#23)
		-0.8.27 (contracts/test/MessageProxyCaller.sol#22)
		-0.8.27 (contracts/test/MessageProxyForMainnetTester.sol#22)
		-0.8.27 (contracts/test/MessageProxyForSchainTester.sol#22)
		-0.8.27 (contracts/test/MessageProxyForSchainWithoutSignature.sol#22)
		-0.8.27 (contracts/test/MessagesTester.sol#23)
		-0.8.27 (contracts/test/PrecompiledMock.sol#22)
		-0.8.27 (contracts/test/ReceiverGasLimitMainnetMock.sol#23)
		-0.8.27 (contracts/test/ReceiverGasLimitSchainMock.sol#23)
		-0.8.27 (contracts/test/ReceiverMock.sol#23)
		-0.8.27 (contracts/test/SafeMock.sol#22)
		-0.8.27 (contracts/test/SkaleManagerMock.sol#22)
		-0.8.27 (contracts/test/SkaleVerifierMock.sol#23)
		-0.8.27 (contracts/test/TestCallReceiverContract.sol#23)
		-0.8.27 (contracts/test/TestContractManager.sol#22)
		-0.8.27 (contracts/test/TestNodes.sol#23)
		-0.8.27 (contracts/test/TestSchains.sol#23)
		-0.8.27 (contracts/test/TestSchainsInternal.sol#23)
		-0.8.27 (contracts/test/TestWallets.sol#22)
		-0.8.27 (contracts/test/erc20/ERC20IncorrectTransfer.sol#3)
		-0.8.27 (contracts/test/erc20/ERC20TransferWithFalseReturn.sol#3)
		-0.8.27 (contracts/test/erc20/ERC20TransferWithoutReturn.sol#3)
		-0.8.27 (contracts/test/erc20/ERC20WithoutTransfer.sol#3)
		-0.8.27 (contracts/test/erc20/RevertableERC20.sol#22)
		-0.8.27 (contracts/thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol#3)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#different-pragma-directives-are-used

ReceiverGasLimitMainnetMock.postMessage(SchainHash,address,bytes) (contracts/test/ReceiverGasLimitMainnetMock.sol#30-41) has costly operations inside a loop:
	- a ++ (contracts/test/ReceiverGasLimitMainnetMock.sol#39)
ReceiverGasLimitSchainMock.postMessage(SchainHash,address,bytes) (contracts/test/ReceiverGasLimitSchainMock.sol#30-41) has costly operations inside a loop:
	- a ++ (contracts/test/ReceiverGasLimitSchainMock.sol#39)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#costly-operations-inside-a-loop

AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init_unchained() (@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol#22-23) is never used and should be removed
AccessControlUpgradeable.__AccessControl_init_unchained() (@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol#79-80) is never used and should be removed
ContextUpgradeable.__Context_init() (@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol#18-19) is never used and should be removed
ContextUpgradeable.__Context_init_unchained() (@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol#21-22) is never used and should be removed
ContextUpgradeable._contextSuffixLength() (@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol#31-33) is never used and should be removed
ContextUpgradeable._msgData() (@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol#27-29) is never used and should be removed
DepositBoxERC721._receiveERC721(string,address,address,uint256) (contracts/mainnet/DepositBoxes/DepositBoxERC721.sol#296-321) is never used and should be removed
ERC1155BurnableUpgradeable.__ERC1155Burnable_init_unchained() (@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol#19-20) is never used and should be removed
ERC1155ReceiverUpgradeable.__ERC1155Receiver_init_unchained() (@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol#17-18) is never used and should be removed
ERC1155ReceiverUpgradeableWithoutGap.__ERC1155Receiver_init() (contracts/thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol#28-31) is never used and should be removed
ERC1155ReceiverUpgradeableWithoutGap.__ERC1155Receiver_init_unchained() (contracts/thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol#34-35) is never used and should be removed
ERC165Upgradeable.__ERC165_init() (@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol#24-25) is never used and should be removed
ERC165Upgradeable.__ERC165_init_unchained() (@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol#27-28) is never used and should be removed
ERC20BurnableUpgradeable.__ERC20Burnable_init_unchained() (@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol#19-20) is never used and should be removed
ERC721BurnableUpgradeable.__ERC721Burnable_init_unchained() (@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol#18-19) is never used and should be removed
ERC721URIStorageUpgradeable.__ERC721URIStorage_init() (@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol#19-20) is never used and should be removed
ERC721URIStorageUpgradeable.__ERC721URIStorage_init_unchained() (@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol#22-23) is never used and should be removed
ERC721Upgradeable.__unsafe_increaseBalance(address,uint256) (@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol#468-470) is never used and should be removed
ERC721Upgradeable._safeMint(address,uint256) (@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol#241-243) is never used and should be removed
ERC721Upgradeable._safeMint(address,uint256,bytes) (@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol#249-255) is never used and should be removed
Initializable._disableInitializers() (@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol#145-151) is never used and should be removed
Initializable._getInitializedVersion() (@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol#156-158) is never used and should be removed
Initializable._isInitializing() (@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol#163-165) is never used and should be removed
KeyStorage._getConfigVariableUint256(string) (contracts/schain/KeyStorage.sol#73-95) is never used and should be removed
KeyStorage._getCurrentBLSPublicKey() (contracts/schain/KeyStorage.sol#100-125) is never used and should be removed
MessageProxyForSchain._getEtherbase() (contracts/schain/MessageProxyForSchain.sol#412-414) is never used and should be removed
MessageProxyForSchain._verifyMessages(bytes32,IMessageListener.Signature) (contracts/schain/MessageProxyForSchain.sol#375-395) is never used and should be removed
TokenManagerERC721._exit(SchainHash,address,address,address,uint256) (contracts/schain/TokenManagers/TokenManagerERC721.sol#317-352) is never used and should be removed
TokenManagerERC721._receiveERC721(SchainHash,address,address,uint256) (contracts/schain/TokenManagers/TokenManagerERC721.sol#273-296) is never used and should be removed
TokenManagerERC721._sendERC721(SchainHash,bytes) (contracts/schain/TokenManagers/TokenManagerERC721.sol#212-254) is never used and should be removed
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#dead-code

Version constraint ^0.8.0 contains known severe issues (https://solidity.readthedocs.io/en/latest/bugs.html)
	- FullInlinerNonExpressionSplitArgumentEvaluationOrder
	- MissingSideEffectsOnSelectorAccess
	- AbiReencodingHeadOverflowWithStaticArrayCleanup
	- DirtyBytesArrayToStorage
	- DataLocationChangeInInternalOverride
	- NestedCalldataArrayAbiReencodingSizeValidation
	- SignedImmutables
	- ABIDecodeTwoDimensionalArrayMemory
	- KeccakCaching.
It is used by:
	- ^0.8.0 (@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol#4)
	- ^0.8.0 (@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol#4)
	- ^0.8.0 (@openzeppelin/contracts-upgradeable/access/IAccessControlEnumerableUpgradeable.sol#4)
	- ^0.8.0 (@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol#4)
	- ^0.8.0 (@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol#4)
	- ^0.8.0 (@openzeppelin/contracts-upgradeable/interfaces/IERC165Upgradeable.sol#4)
	- ^0.8.0 (@openzeppelin/contracts-upgradeable/interfaces/IERC4906Upgradeable.sol#4)
	- ^0.8.0 (@openzeppelin/contracts-upgradeable/interfaces/IERC721Upgradeable.sol#4)
	- ^0.8.0 (@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol#4)
	- ^0.8.0 (@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol#4)
	- ^0.8.0 (@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol#4)
	- ^0.8.0 (@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol#4)
	- ^0.8.0 (@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol#4)
	- ^0.8.0 (@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol#4)
	- ^0.8.0 (@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol#4)
	- ^0.8.0 (@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol#4)
	- ^0.8.0 (@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol#4)
	- ^0.8.0 (@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol#4)
	- ^0.8.0 (@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20PermitUpgradeable.sol#4)
	- ^0.8.0 (@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol#4)
	- ^0.8.0 (@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol#4)
	- ^0.8.0 (@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol#4)
	- ^0.8.0 (@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol#4)
	- ^0.8.0 (@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol#4)
	- ^0.8.0 (@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol#4)
	- ^0.8.0 (@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol#4)
	- ^0.8.0 (@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol#4)
	- ^0.8.0 (@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol#4)
	- ^0.8.0 (@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol#4)
	- ^0.8.0 (@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol#4)
	- ^0.8.0 (@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol#4)
	- ^0.8.0 (@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol#5)
	- ^0.8.0 (@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol#4)
	- ^0.8.0 (@openzeppelin/contracts-upgradeable/utils/math/SignedMathUpgradeable.sol#4)
	- ^0.8.0 (@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol#5)
	- ^0.8.0 (@skalenetwork/etherbase-interfaces/IEtherbase.sol#23)
	- ^0.8.0 (@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol#23)
Version constraint ^0.8.2 contains known severe issues (https://solidity.readthedocs.io/en/latest/bugs.html)
	- FullInlinerNonExpressionSplitArgumentEvaluationOrder
	- MissingSideEffectsOnSelectorAccess
	- AbiReencodingHeadOverflowWithStaticArrayCleanup
	- DirtyBytesArrayToStorage
	- DataLocationChangeInInternalOverride
	- NestedCalldataArrayAbiReencodingSizeValidation
	- SignedImmutables
	- ABIDecodeTwoDimensionalArrayMemory
	- KeccakCaching.
It is used by:
	- ^0.8.2 (@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol#4)
Version constraint ^0.8.1 contains known severe issues (https://solidity.readthedocs.io/en/latest/bugs.html)
	- FullInlinerNonExpressionSplitArgumentEvaluationOrder
	- MissingSideEffectsOnSelectorAccess
	- AbiReencodingHeadOverflowWithStaticArrayCleanup
	- DirtyBytesArrayToStorage
	- DataLocationChangeInInternalOverride
	- NestedCalldataArrayAbiReencodingSizeValidation
	- SignedImmutables
	- ABIDecodeTwoDimensionalArrayMemory
	- KeccakCaching.
It is used by:
	- ^0.8.1 (@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol#4)
Version constraint ^0.8.4 contains known severe issues (https://solidity.readthedocs.io/en/latest/bugs.html)
	- FullInlinerNonExpressionSplitArgumentEvaluationOrder
	- MissingSideEffectsOnSelectorAccess
	- AbiReencodingHeadOverflowWithStaticArrayCleanup
	- DirtyBytesArrayToStorage
	- DataLocationChangeInInternalOverride
	- NestedCalldataArrayAbiReencodingSizeValidation
	- SignedImmutables.
It is used by:
	- ^0.8.4 (@openzeppelin/contracts-upgradeable/utils/structs/DoubleEndedQueueUpgradeable.sol#3)
Version constraint >=0.8.19<0.9.0 is too complex.
It is used by:
	- >=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/DomainTypes.sol#21)
	- >=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/IGasReimbursable.sol#22)
	- >=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/IMessageListener.sol#22)
	- >=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/IMessageProxy.sol#22)
	- >=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/IMessageReceiver.sol#22)
	- >=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataMainnet.sol#22)
	- >=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataSchain.sol#22)
	- >=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC1155.sol#22)
	- >=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC20.sol#22)
	- >=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC721.sol#22)
	- >=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol#22)
	- >=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol#22)
	- >=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/mainnet/IDepositBox.sol#22)
	- >=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/mainnet/ILinker.sol#22)
	- >=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/mainnet/IMessageProxyForMainnet.sol#22)
	- >=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/mainnet/ISkaleManagerClient.sol#22)
	- >=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/mainnet/ITwin.sol#22)
	- >=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol#22)
	- >=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/schain/IKeyStorage.sol#22)
	- >=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/schain/IMessageProxyForSchain.sol#22)
	- >=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/schain/ITokenManager.sol#22)
	- >=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/schain/ITokenManagerLinker.sol#22)
	- >=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenContractManager.sol#22)
	- >=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC1155.sol#22)
	- >=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC20.sol#22)
	- >=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC721.sol#22)
	- >=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerEth.sol#22)
	- >=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/schain/bls/IFieldOperations.sol#22)
	- >=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/schain/tokens/IERC1155OnChain.sol#22)
	- >=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/schain/tokens/IERC20OnChain.sol#22)
	- >=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/schain/tokens/IERC721OnChain.sol#22)
	- >=0.8.19<0.9.0 (@skalenetwork/ima-interfaces/schain/tokens/IEthErc20.sol#22)
Version constraint >=0.6.10<0.9.0 is too complex.
It is used by:
	- >=0.6.10<0.9.0 (@skalenetwork/skale-manager-interfaces/IContractManager.sol#22)
	- >=0.6.10<0.9.0 (@skalenetwork/skale-manager-interfaces/INodes.sol#22)
	- >=0.6.10<0.9.0 (@skalenetwork/skale-manager-interfaces/ISchains.sol#22)
	- >=0.6.10<0.9.0 (@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol#22)
	- >=0.6.10<0.9.0 (@skalenetwork/skale-manager-interfaces/IWallets.sol#22)
	- >=0.6.10<0.9.0 (@skalenetwork/skale-manager-interfaces/utils/IRandom.sol#22)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-versions-of-solidity

Low level call in SafeERC20Upgradeable._callOptionalReturnBool(IERC20Upgradeable,bytes) (@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol#134-142):
	- (success,returndata) = address(token).call(data) (@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol#139)
Low level call in AddressUpgradeable.sendValue(address,uint256) (@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol#64-69):
	- (success,None) = recipient.call{value: amount}() (@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol#67)
Low level call in AddressUpgradeable.functionCallWithValue(address,bytes,uint256,string) (@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol#128-137):
	- (success,returndata) = target.call{value: value}(data) (@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol#135)
Low level call in AddressUpgradeable.functionStaticCall(address,bytes,string) (@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol#155-162):
	- (success,returndata) = target.staticcall(data) (@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol#160)
Low level call in AddressUpgradeable.functionDelegateCall(address,bytes,string) (@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol#180-187):
	- (success,returndata) = target.delegatecall(data) (@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol#185)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#low-level-calls

ERC20OnChain (contracts/schain/tokens/ERC20OnChain.sol#34-64) should inherit from IERC20TransferWithFalseReturn (contracts/test/erc20/ERC20TransferWithFalseReturn.sol#7-9)
EthErc20 (contracts/schain/tokens/EthErc20.sol#33-84) should inherit from IERC20TransferWithFalseReturn (contracts/test/erc20/ERC20TransferWithFalseReturn.sol#7-9)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#missing-inheritance

Function AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init() (@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol#19-20) is not in mixedCase
Function AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init_unchained() (@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol#22-23) is not in mixedCase
Variable AccessControlEnumerableUpgradeable.__gap (@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol#76) is not in mixedCase
Function AccessControlUpgradeable.__AccessControl_init() (@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol#76-77) is not in mixedCase
Function AccessControlUpgradeable.__AccessControl_init_unchained() (@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol#79-80) is not in mixedCase
Variable AccessControlUpgradeable.__gap (@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol#260) is not in mixedCase
Function OwnableUpgradeable.__Ownable_init() (@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol#29-31) is not in mixedCase
Function OwnableUpgradeable.__Ownable_init_unchained() (@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol#33-35) is not in mixedCase
Variable OwnableUpgradeable.__gap (@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol#94) is not in mixedCase
Function ERC1155Upgradeable.__ERC1155_init(string) (@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol#36-38) is not in mixedCase
Function ERC1155Upgradeable.__ERC1155_init_unchained(string) (@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol#40-42) is not in mixedCase
Variable ERC1155Upgradeable.__gap (@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol#508) is not in mixedCase
Function ERC1155BurnableUpgradeable.__ERC1155Burnable_init() (@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol#16-17) is not in mixedCase
Function ERC1155BurnableUpgradeable.__ERC1155Burnable_init_unchained() (@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol#19-20) is not in mixedCase
Variable ERC1155BurnableUpgradeable.__gap (@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol#44) is not in mixedCase
Function ERC1155ReceiverUpgradeable.__ERC1155Receiver_init() (@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol#14-15) is not in mixedCase
Function ERC1155ReceiverUpgradeable.__ERC1155Receiver_init_unchained() (@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol#17-18) is not in mixedCase
Variable ERC1155ReceiverUpgradeable.__gap (@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol#31) is not in mixedCase
Function ERC20Upgradeable.__ERC20_init(string,string) (@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol#55-57) is not in mixedCase
Function ERC20Upgradeable.__ERC20_init_unchained(string,string) (@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol#59-62) is not in mixedCase
Variable ERC20Upgradeable.__gap (@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol#376) is not in mixedCase
Function ERC20BurnableUpgradeable.__ERC20Burnable_init() (@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol#16-17) is not in mixedCase
Function ERC20BurnableUpgradeable.__ERC20Burnable_init_unchained() (@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol#19-20) is not in mixedCase
Variable ERC20BurnableUpgradeable.__gap (@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol#51) is not in mixedCase
Function IERC20PermitUpgradeable.DOMAIN_SEPARATOR() (@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20PermitUpgradeable.sol#89) is not in mixedCase
Function ERC721Upgradeable.__ERC721_init(string,string) (@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol#45-47) is not in mixedCase
Function ERC721Upgradeable.__ERC721_init_unchained(string,string) (@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol#49-52) is not in mixedCase
Function ERC721Upgradeable.__unsafe_increaseBalance(address,uint256) (@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol#468-470) is not in mixedCase
Variable ERC721Upgradeable.__gap (@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol#477) is not in mixedCase
Function ERC721BurnableUpgradeable.__ERC721Burnable_init() (@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol#15-16) is not in mixedCase
Function ERC721BurnableUpgradeable.__ERC721Burnable_init_unchained() (@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol#18-19) is not in mixedCase
Variable ERC721BurnableUpgradeable.__gap (@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol#38) is not in mixedCase
Function ERC721URIStorageUpgradeable.__ERC721URIStorage_init() (@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol#19-20) is not in mixedCase
Function ERC721URIStorageUpgradeable.__ERC721URIStorage_init_unchained() (@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol#22-23) is not in mixedCase
Variable ERC721URIStorageUpgradeable.__gap (@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol#86) is not in mixedCase
Function ContextUpgradeable.__Context_init() (@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol#18-19) is not in mixedCase
Function ContextUpgradeable.__Context_init_unchained() (@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol#21-22) is not in mixedCase
Variable ContextUpgradeable.__gap (@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol#40) is not in mixedCase
Function ERC165Upgradeable.__ERC165_init() (@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol#24-25) is not in mixedCase
Function ERC165Upgradeable.__ERC165_init_unchained() (@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol#27-28) is not in mixedCase
Variable ERC165Upgradeable.__gap (@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol#41) is not in mixedCase
Parameter SafeMock.getTransactionHash(address,uint256,bytes,ISafeMock.Operation,uint256,uint256,uint256,address,address,uint256)._nonce (contracts/test/SafeMock.sol#135) is not in mixedCase
Function ERC1155ReceiverUpgradeableWithoutGap.__ERC1155Receiver_init() (contracts/thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol#28-31) is not in mixedCase
Function ERC1155ReceiverUpgradeableWithoutGap.__ERC1155Receiver_init_unchained() (contracts/thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol#34-35) is not in mixedCase
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#conformance-to-solidity-naming-conventions

KeyStorageMock.hello (contracts/test/KeyStorageMock.sol#38) should be constant 
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#state-variables-that-could-be-declared-constant

ContractManager.owner (contracts/test/TestContractManager.sol#37) should be immutable 
ERC20WithoutTransfer._decimals (contracts/test/erc20/ERC20WithoutTransfer.sol#30) should be immutable 
FallbackEthTester.communityPool (contracts/test/FallbackEthTester.sol#38) should be immutable 
FallbackEthTester.depositBoxEth (contracts/test/FallbackEthTester.sol#37) should be immutable 
SkaleManagerMock.contractManager (contracts/test/SkaleManagerMock.sol#31) should be immutable 
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#state-variables-that-could-be-declared-immutable
. analyzed (163 contracts with 100 detectors), 198 result(s) found
Metadata
{
    "solc": {
        "status": "ok",
        "use_rc": 0,
        "version": "0.8.27",
        "strategy": "solc-select",
        "solc_path": "/var/www/tripwire/.venv/bin/solc",
        "install_rc": 0,
        "use_stderr": null,
        "use_stdout": "Switched global version to 0.8.27",
        "install_stderr": null,
        "install_stdout": "Version '0.8.27' is already installed, skipping..."
    },
    "solc_args": "--base-path /tmp/slither-3rzqsamt --include-path /tmp/slither-3rzqsamt/lib --include-path /tmp/slither-3rzqsamt/lib/openzeppelin-contracts --allow-paths /tmp/slither-3rzqsamt,/tmp/slither-3rzqsamt/lib,/tmp/slither-3rzqsamt/lib/openzeppelin-contracts,/tmp/slither-3rzqsamt/src",
    "remappings": [
        "openzeppelin-contracts/=lib/openzeppelin-contracts/"
    ],
    "source_files": [
        "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol",
        "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol",
        "@openzeppelin/contracts-upgradeable/access/IAccessControlEnumerableUpgradeable.sol",
        "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol",
        "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol",
        "@openzeppelin/contracts-upgradeable/interfaces/IERC165Upgradeable.sol",
        "@openzeppelin/contracts-upgradeable/interfaces/IERC4906Upgradeable.sol",
        "@openzeppelin/contracts-upgradeable/interfaces/IERC721Upgradeable.sol",
        "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol",
        "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol",
        "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol",
        "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol",
        "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol",
        "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol",
        "@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol",
        "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol",
        "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol",
        "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol",
        "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20PermitUpgradeable.sol",
        "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol",
        "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol",
        "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol",
        "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol",
        "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol",
        "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol",
        "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol",
        "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol",
        "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol",
        "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol",
        "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol",
        "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol",
        "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol",
        "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol",
        "@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol",
        "@openzeppelin/contracts-upgradeable/utils/math/SignedMathUpgradeable.sol",
        "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol",
        "@openzeppelin/contracts-upgradeable/utils/structs/DoubleEndedQueueUpgradeable.sol",
        "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol",
        "@skalenetwork/etherbase-interfaces/IEtherbase.sol",
        "@skalenetwork/etherbase-interfaces/IEtherbaseUpgradeable.sol",
        "@skalenetwork/ima-interfaces/DomainTypes.sol",
        "@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataMainnet.sol",
        "@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataSchain.sol",
        "@skalenetwork/ima-interfaces/IGasReimbursable.sol",
        "@skalenetwork/ima-interfaces/IMessageListener.sol",
        "@skalenetwork/ima-interfaces/IMessageProxy.sol",
        "@skalenetwork/ima-interfaces/IMessageReceiver.sol",
        "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC1155.sol",
        "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC20.sol",
        "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxERC721.sol",
        "@skalenetwork/ima-interfaces/mainnet/DepositBoxes/IDepositBoxEth.sol",
        "@skalenetwork/ima-interfaces/mainnet/ICommunityPool.sol",
        "@skalenetwork/ima-interfaces/mainnet/IDepositBox.sol",
        "@skalenetwork/ima-interfaces/mainnet/ILinker.sol",
        "@skalenetwork/ima-interfaces/mainnet/IMessageProxyForMainnet.sol",
        "@skalenetwork/ima-interfaces/mainnet/ISkaleManagerClient.sol",
        "@skalenetwork/ima-interfaces/mainnet/ITwin.sol",
        "@skalenetwork/ima-interfaces/schain/bls/IFieldOperations.sol",
        "@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol",
        "@skalenetwork/ima-interfaces/schain/IKeyStorage.sol",
        "@skalenetwork/ima-interfaces/schain/IMessageProxyForSchain.sol",
        "@skalenetwork/ima-interfaces/schain/ITokenManager.sol",
        "@skalenetwork/ima-interfaces/schain/ITokenManagerLinker.sol",
        "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenContractManager.sol",
        "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC1155.sol",
        "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC20.sol",
        "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC721.sol",
        "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerEth.sol",
        "@skalenetwork/ima-interfaces/schain/tokens/IERC1155OnChain.sol",
        "@skalenetwork/ima-interfaces/schain/tokens/IERC20OnChain.sol",
        "@skalenetwork/ima-interfaces/schain/tokens/IERC721OnChain.sol",
        "@skalenetwork/ima-interfaces/schain/tokens/IEthErc20.sol",
        "@skalenetwork/skale-manager-interfaces/IContractManager.sol",
        "@skalenetwork/skale-manager-interfaces/INodes.sol",
        "@skalenetwork/skale-manager-interfaces/ISchains.sol",
        "@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol",
        "@skalenetwork/skale-manager-interfaces/IWallets.sol",
        "@skalenetwork/skale-manager-interfaces/utils/IRandom.sol",
        "contracts/extensions/ERC721ReferenceMintAndMetadataMainnet.sol",
        "contracts/extensions/ERC721ReferenceMintAndMetadataSchain.sol",
        "contracts/extensions/interfaces/MessageProxyClient.sol",
        "contracts/extensions/interfaces/MessageReceiver.sol",
        "contracts/extensions/interfaces/MessageSender.sol",
        "contracts/mainnet/CommunityPool.sol",
        "contracts/mainnet/DepositBox.sol",
        "contracts/mainnet/DepositBoxes/DepositBoxERC1155.sol",
        "contracts/mainnet/DepositBoxes/DepositBoxERC20.sol",
        "contracts/mainnet/DepositBoxes/DepositBoxERC721.sol",
        "contracts/mainnet/DepositBoxes/DepositBoxERC721WithMetadata.sol",
        "contracts/mainnet/DepositBoxes/DepositBoxEth.sol",
        "contracts/mainnet/Linker.sol",
        "contracts/mainnet/MessageProxyForMainnet.sol",
        "contracts/mainnet/SkaleManagerClient.sol",
        "contracts/mainnet/Twin.sol",
        "contracts/MessageProxy.sol",
        "contracts/Messages.sol",
        "contracts/schain/bls/FieldOperations.sol",
        "contracts/schain/bls/Precompiled.sol",
        "contracts/schain/bls/SkaleVerifier.sol",
        "contracts/schain/CommunityLocker.sol",
        "contracts/schain/DefaultAddresses.sol",
        "contracts/schain/KeyStorage.sol",
        "contracts/schain/MessageProxyForSchain.sol",
        "contracts/schain/TokenManager.sol",
        "contracts/schain/TokenManagerLinker.sol",
        "contracts/schain/TokenManagers/TokenManagerERC1155.sol",
        "contracts/schain/TokenManagers/TokenManagerERC20.sol",
        "contracts/schain/TokenManagers/TokenManagerERC721.sol",
        "contracts/schain/TokenManagers/TokenManagerERC721WithMetadata.sol",
        "contracts/schain/TokenManagers/TokenManagerEth.sol",
        "contracts/schain/tokens/ERC1155OnChain.sol",
        "contracts/schain/tokens/ERC20OnChain.sol",
        "contracts/schain/tokens/ERC721OnChain.sol",
        "contracts/schain/tokens/EthErc20.sol",
        "contracts/test/ConfigReader.sol",
        "contracts/test/erc20/ERC20IncorrectTransfer.sol",
        "contracts/test/erc20/ERC20TransferWithFalseReturn.sol",
        "contracts/test/erc20/ERC20TransferWithoutReturn.sol",
        "contracts/test/erc20/ERC20WithoutTransfer.sol",
        "contracts/test/erc20/RevertableERC20.sol",
        "contracts/test/EtherbaseMock.sol",
        "contracts/test/FallbackEthTester.sol",
        "contracts/test/KeyStorageMock.sol",
        "contracts/test/Logger.sol",
        "contracts/test/MessageProxyCaller.sol",
        "contracts/test/MessageProxyForMainnetTester.sol",
        "contracts/test/MessageProxyForSchainTester.sol",
        "contracts/test/MessageProxyForSchainWithoutSignature.sol",
        "contracts/test/MessagesTester.sol",
        "contracts/test/PrecompiledMock.sol",
        "contracts/test/ReceiverGasLimitMainnetMock.sol",
        "contracts/test/ReceiverGasLimitSchainMock.sol",
        "contracts/test/ReceiverMock.sol",
        "contracts/test/SafeMock.sol",
        "contracts/test/SkaleManagerMock.sol",
        "contracts/test/SkaleVerifierMock.sol",
        "contracts/test/TestCallReceiverContract.sol",
        "contracts/test/TestContractManager.sol",
        "contracts/test/TestNodes.sol",
        "contracts/test/TestSchains.sol",
        "contracts/test/TestSchainsInternal.sol",
        "contracts/test/TestWallets.sol",
        "contracts/thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol"
    ],
    "contract_count": 0,
    "contract_names": [],
    "detector_count": 198,
    "workspace_hash": "10d3067194bafc5f567da894ac1c65d33341c2e092cfbe71cce831784955701d",
    "duration_seconds": 15.020244359970093,
    "solc_version_requested": "0.8.27"
}

Codex

report.consolidate
Job Status
complete
Attempts
1 / 6
Findings
3
No findings?
no
Summary
Found a high-severity ERC20 accounting break on lock, a medium-severity delayed-withdrawal claim-loss bug, and a low-severity unauthenticated oracle setter.
View stdout
{"no_findings":false,"summary":"Found a high-severity ERC20 accounting break on lock, a medium-severity delayed-withdrawal claim-loss bug, and a low-severity unauthenticated oracle setter.","findings":[{"severity":"high","category":"other","title":"ERC20 bridge accounting trusts the requested amount instead of the amount actually received","exploit_scenario":"A user bridges a fee-on-transfer or deflationary ERC20. `DepositBoxERC20` records and messages the full `amount` before/without checking how many tokens the bridge actually received. The destination chain credits the full amount, but the source bridge locked less. The attacker can later exit the full credited balance and drain other users' liquidity or leave the bridge permanently undercollateralized. The same nominal-amount assumption exists in the schain-native ERC20 path when a token is locked for schain-to-schain transfer.","recommendation":"Measure `balanceBefore`/`balanceAfter` around every ERC20 pull and bridge only the actual received amount. Revert if the received amount is smaller than requested unless the token type is explicitly unsupported. Apply the same balance-delta accounting anywhere ERC20s are locked rather than burned.","evidence":"On mainnet, the code builds the outbound message and increments `transferredAmount` using the caller-supplied `amount`, then performs `safeTransferFrom` with no balance-delta check. On schain-native ERC20 transfers, `_saveTransferredAmount(..., amount)` is also done before `transferFrom`, again assuming the nominal amount was received.","locations":["contracts/mainnet/DepositBoxes/DepositBoxERC20.sol:698","contracts/mainnet/DepositBoxes/DepositBoxERC20.sol:704","contracts/mainnet/DepositBoxes/DepositBoxERC20.sol:705","contracts/schain/TokenManagers/TokenManagerERC20.sol:339","contracts/schain/TokenManagers/TokenManagerERC20.sol:348","contracts/schain/TokenManagers/TokenManagerERC20.sol:350"]},{"severity":"medium","category":"other","title":"Delayed ERC20 withdrawals clear user claims before confirming token delivery","exploit_scenario":"When a delayed transfer becomes withdrawable, `retrieveFor` marks it completed or deletes it from the queue before attempting the ERC20 transfer. If the token transfer then fails, the call is swallowed and only `TransferSkipped` is emitted. A token admin can pause or blacklist transfers right before unlock, or a nonstandard token can fail transfer, causing the receiver's claim to be irreversibly erased while the tokens remain stuck in the bridge contract.","recommendation":"Do not mutate delayed-transfer state until the token transfer succeeds. Revert failed payouts, or leave the transfer pending so the user can retry later. If partial progress is needed, persist an explicit failed state with an admin/user recovery path instead of deleting the claim.","evidence":"`retrieveFor` removes or marks transfers as `COMPLETED` before calling `_doNTransfers`. `_doNTransfers` catches transfer failures and only emits `TransferSkipped`, without restoring the queue entry or status.","locations":["contracts/mainnet/DepositBoxes/DepositBoxERC20.sol:631","contracts/mainnet/DepositBoxes/DepositBoxERC20.sol:635","contracts/mainnet/DepositBoxes/DepositBoxERC20.sol:651","contracts/mainnet/DepositBoxes/DepositBoxERC20.sol:734","contracts/mainnet/DepositBoxes/DepositBoxERC20.sol:737"]},{"severity":"low","category":"oracle","title":"`CommunityLocker.setGasPrice` accepts arbitrary caller-supplied oracle values","exploit_scenario":"Any account can update `mainnetGasPrice` and `gasPriceTimestamp` by calling `setGasPrice`; the signature parameter is unused and the verification check is commented out. Today this state is not consumed elsewhere in first-party code, so impact is limited, but if operators or future upgrades rely on it, an attacker can feed arbitrary prices and timestamps.","recommendation":"Require a verified signature or strict role-based authorization before updating oracle state. If the oracle is not live yet, disable the entrypoint rather than accepting unauthenticated writes.","evidence":"The function has no access-control modifier, the signature argument is unnamed/unused, and the intended `messageProxy.verifySignature(...)` check is commented out.","locations":["contracts/schain/CommunityLocker.sol:252","contracts/schain/CommunityLocker.sol:257","contracts/schain/CommunityLocker.sol:262","contracts/schain/CommunityLocker.sol:272"]}]}
View stderr
ame);
        }
        connected = connected && messageProxy.isConnectedChain(schainName);
    }
}

exec
/bin/bash -lc "sed -n '1,340p' contracts/schain/CommunityLocker.sol" in /tmp/codex-sryvig8b
 succeeded in 0ms:
// SPDX-License-Identifier: AGPL-3.0-only

/*
    CommunityLocker.sol - SKALE Manager
    Copyright (C) 2021-Present SKALE Labs
    @author Dmytro Stebaiev
    @author Artem Payvin
    @author Vadim Yavorsky

    SKALE Manager is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published
    by the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    SKALE Manager is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with SKALE Manager.  If not, see <https://www.gnu.org/licenses/>.
*/

pragma solidity 0.8.27;

import "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol";
import "@skalenetwork/ima-interfaces/schain/ICommunityLocker.sol";

import "../Messages.sol";

interface ICommunityLockerInitializer is ICommunityLocker {
    function initializeTimestamp() external;
}


/**
 * @title CommunityLocker
 * @dev Contract contains logic to perform automatic reimbursement
 * of gas fees for sent messages
 */
contract CommunityLocker is ICommunityLockerInitializer, AccessControlEnumerableUpgradeable {

    /**
     * @dev Mainnet identifier.
     */
    string constant public MAINNET_NAME = "Mainnet";

    /**
     * @dev Keccak256 hash of mainnet name.
     */
    SchainHash constant public MAINNET_HASH = SchainHash.wrap(keccak256(abi.encodePacked(MAINNET_NAME)));

    /**
     * @dev id of a role that allows changing of the contract parameters.
     */
    bytes32 public constant CONSTANT_SETTER_ROLE = keccak256("CONSTANT_SETTER_ROLE");

    /**
     * @dev Address of MessageProxyForSchain.
     */
    IMessageProxyForSchain public messageProxy;

    /**
     * @dev Address of TokenManagerLinker.
     */
    ITokenManagerLinker public tokenManagerLinker;

    /**
     * @dev Address of CommunityPool on mainnet.
     */
    address public communityPool;

    /**
     * @dev Keccak256 hash of schain name.
     */
    /// @custom:oz-retyped-from bytes32
    SchainHash public schainHash;

    // Disable slither check due to variable depreciation
    // and unavailability of making it constant because
    // it breaks upgradeability pattern.
    // slither-disable-next-line constable-states
    uint private _deprecatedTimeLimitPerMessage;

    /**
     * @dev Mapping of users who are allowed to send a message.
     */
    // user address => allowed to send message
    mapping(address => bool) public activeUsers;

    /**
     * @dev Timestamp of previous sent message by user.
     */
    // user address => timestamp of last message
    mapping(address => uint) public lastMessageTimeStamp;

    /**
     * @dev mainnet gas price(baseFee) value
     */
    uint256 public mainnetGasPrice;

    /**
     * @dev Timestamp of previous set of mainnet gas price
     */
    uint256 public gasPriceTimestamp;

    /**
     * @dev Amount of seconds after message sending
     * when next message cannot be sent.
     */
    // schainHash   => time limit
    /// @custom:oz-retyped-from mapping(bytes32 => uint256)
    mapping(SchainHash => uint) public timeLimitPerMessage;

    /**
     * @dev Timestamp of previous sent message by user during
     * schain to schain transfers
     */
    // schainHash   =>           user  => timestamp
    /// @custom:oz-retyped-from mapping(bytes32 => mapping(address => uint256))
    mapping(SchainHash => mapping(address => uint)) public lastMessageTimeStampToSchain;

    /**
     * @dev Emitted when a user becomes active.
     */
    event ActivateUser(
        SchainHash schainHash,
        address user
    );

    /**
     * @dev Emitted when a user stops being active.
     */
    event LockUser(
        SchainHash schainHash,
        address user
    );

    /**
     * @dev Emitted when constants updated.
     */
    event ConstantUpdated(
        bytes32 indexed constantHash,
        uint previousValue,
        uint newValue
    );

    modifier checkUserBeforeTransfer(SchainHash chainHash, address user) {
        uint256 lastTimestamp = lastMessageTimeStampToSchain[chainHash][user];
        if (chainHash == MAINNET_HASH) {
            require(activeUsers[user], "Recipient must be active");
            lastTimestamp = lastMessageTimeStamp[user];
        }
        require(
            lastTimestamp + timeLimitPerMessage[chainHash] < block.timestamp,
            "Exceeded message rate limit"
        );
        _;
    }

    /**
     * @dev Allows MessageProxy to post operational message from mainnet
     * or SKALE chains.
     *
     * Requirements:
     *
     * - MessageProxy must be the caller of the function.
     * - CommunityPool must be an origin of the message on mainnet.
     * - The message must come from the mainnet.
     * - The message must contains status of a user.
     * - Status of a user in the message must be different from the current status.
     */
    function postMessage(
        SchainHash fromChainHash,
        address sender,
        bytes calldata data
    )
        external
        override
    {
        require(msg.sender == address(messageProxy), "Sender is not a message proxy");
        require(sender == communityPool, "Sender must be CommunityPool");
        require(fromChainHash == MAINNET_HASH, "Source chain name must be Mainnet");
        Messages.MessageType operation = Messages.getMessageType(data);
        require(operation == Messages.MessageType.USER_STATUS, "The message should contain a status of user");
        Messages.UserStatusMessage memory message = Messages.decodeUserStatusMessage(data);
        require(activeUsers[message.receiver] != message.isActive, "Active user statuses must be different");
        activeUsers[message.receiver] = message.isActive;
        if (message.isActive) {
            emit ActivateUser(schainHash, message.receiver);
        } else {
            emit LockUser(schainHash, message.receiver);
        }
    }

    /**
     * @dev Reverts if {receiver} is not allowed to send a message.
     *
     * Requirements:
     *
     * - Function caller has to be registered in TokenManagerLinker as a TokenManager.
     * - {receiver} must be an active user.
     * - Previous message sent by {receiver} must be sent earlier then {timeLimitPerMessage} seconds before current time
     * or there are no messages sent by {receiver}.
     */
    function checkAllowedToSendMessage(SchainHash chainHash, address receiver)
        external
        checkUserBeforeTransfer(chainHash, receiver)
        override
    {
        require(
            tokenManagerLinker.hasTokenManager(msg.sender),
            "Sender is not registered token manager"
        );
        if (chainHash == MAINNET_HASH) {
            lastMessageTimeStamp[receiver] = block.timestamp;
        } else {
            lastMessageTimeStampToSchain[chainHash][receiver] = block.timestamp;
        }
    }

    /**
     * @dev Set value of {timeLimitPerMessage} of given chain.
     *
     * Requirements:
     *
     * - Function caller has to be granted with {CONSTANT_SETTER_ROLE}.
     *
     * Emits a {ConstantUpdated} event.
     */
    function setTimeLimitPerMessage(string memory chainName, uint newTimeLimitPerMessage) external override {
        require(hasRole(CONSTANT_SETTER_ROLE, msg.sender), "Not enough permissions to set constant");
        SchainHash chainHash = SchainHash.wrap(keccak256(abi.encodePacked(chainName)));
        require(chainHash != schainHash, "Incorrect chain");
        emit ConstantUpdated(
            keccak256(abi.encodePacked("TimeLimitPerMessage")),
            timeLimitPerMessage[chainHash],
            newTimeLimitPerMessage
        );
        timeLimitPerMessage[chainHash] = newTimeLimitPerMessage;
    }

    /**
     * @dev Set value of {mainnetGasPrice}.
     *
     * Requirements:
     *
     * - Signature should be verified.
     *
     * Emits a {ConstantUpdated} event.
     */
    function setGasPrice(
        uint gasPrice,
        uint timestamp,
        IMessageProxyForSchain.Signature memory
    )
        external
        override
    {
        require(timestamp > gasPriceTimestamp, "Gas price timestamp already updated");
        require(timestamp <= block.timestamp, "Timestamp should not be in the future");
        // TODO: uncomment when oracle finished
        // require(
        //     messageProxy.verifySignature(keccak256(abi.encodePacked(gasPrice, timestamp)), signature),
        //     "Signature is not verified"
        // );
        emit ConstantUpdated(
            keccak256(abi.encodePacked("MainnetGasPrice")),
            mainnetGasPrice,
            gasPrice
        );
        mainnetGasPrice = gasPrice;
        gasPriceTimestamp = timestamp;
    }

    /**
     * @dev Is called once during contract deployment.
     */
    function initialize(
        string memory newSchainName,
        IMessageProxyForSchain newMessageProxy,
        ITokenManagerLinker newTokenManagerLinker,
        address newCommunityPool
    )
        external
        override
        initializer
    {
        require(newCommunityPool != address(0), "Node address has to be set");
        AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();
        _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
        messageProxy = newMessageProxy;
        tokenManagerLinker = newTokenManagerLinker;
        schainHash = SchainHash.wrap(keccak256(abi.encodePacked(newSchainName)));
        timeLimitPerMessage[MAINNET_HASH] = 5 minutes;
        communityPool = newCommunityPool;
    }

    /**
     * @dev Initialize timestamp after upgrade and should be removed after upgrade
     *
     * Requirements:
     * Should be called only by address which hold DEFAULT_ADMIN_ROLE role
     */
    function initializeTimestamp() external override {
        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "Incorrect sender");
        // Disable slither check due to moving data to the new data structure
        // slither-disable-next-line uninitialized-state
        timeLimitPerMessage[MAINNET_HASH] = _deprecatedTimeLimitPerMessage;
        delete _deprecatedTimeLimitPerMessage;
    }
}

exec
/bin/bash -lc "sed -n '1,160p' contracts/schain/DefaultAddresses.sol" in /tmp/codex-sryvig8b
 succeeded in 0ms:
// SPDX-License-Identifier: AGPL-3.0-only

/**
 *   DefaultAddresses.sol - SKALE Interchain Messaging Agent
 *   Copyright (C) 2022-Present SKALE Labs
 *   @author Dmytro Stebaiev
 *
 *   SKALE IMA is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published
 *   by the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   SKALE IMA is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with SKALE IMA.  If not, see <https://www.gnu.org/licenses/>.
 */

 pragma solidity 0.8.27;

library DefaultAddresses {
                                                          // 17 0x00 bytes
    address public constant ETHERBASE = address(0xd2bA3e << (17 * 8));
                                                                       // 16 0x00 bytes
    address public constant TOKEN_MANAGER_LINKER = address(0xD2aAA008 << (16 * 8));
}

exec
/bin/bash -lc "sed -n '1,180p' contracts/schain/KeyStorage.sol" in /tmp/codex-sryvig8b
 succeeded in 0ms:
// SPDX-License-Identifier: AGPL-3.0-only

/**
 *   MessageProxyForSchain.sol - SKALE Interchain Messaging Agent
 *   Copyright (C) 2021-Present SKALE Labs
 *   @author Dmytro Stebaiev
 *
 *   SKALE IMA is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published
 *   by the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   SKALE IMA is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with SKALE IMA.  If not, see <https://www.gnu.org/licenses/>.
 */

pragma solidity 0.8.27;

import "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol";
import "@skalenetwork/ima-interfaces/schain/IKeyStorage.sol";

import "./bls/FieldOperations.sol";


/**
 * @title KeyStorage
 * @dev Holds common BLS public key.
 */
contract KeyStorage is IKeyStorage, AccessControlEnumerableUpgradeable {

    uint256 public constant FREE_MEM_PTR = 0x40;

    /**
     * @dev Address of custom precompiled contract on SKALE chain
     * to get uin256 value from the config.
     */
    uint256 public constant FN_NUM_GET_CONFIG_VARIABLE_UINT256 = 0x13;
    /**
     * @dev Address of custom precompiled contract on SKALE chain
     * to get current BLS public key.
     */
    uint256 public constant FN_NUM_GET_CURRENT_BLS_PUBLIC_KEY = 0x19;

    /**
     * @dev Is called once during contract deployment.
     */
    function initialize()
        external
        override
        initializer
    {
        AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();
        _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
    }

    /**
     * @dev Get BLS common public key.
     */
    function getBlsCommonPublicKey() external view override virtual returns (IFieldOperations.G2Point memory) {
        return _getCurrentBLSPublicKey();
    }

    // private

    /**
     * @dev Get uint256 value from the skaled config.
     */
    function _getConfigVariableUint256(
        string memory strConfigVariableName
    )
        private
        view
        returns ( uint256 rv )
    {
        uint256 fmp = FREE_MEM_PTR;
        uint256 blocks = (bytes(strConfigVariableName).length + 31) / 32 + 1;
        bool success;
        // solhint-disable-next-line no-inline-assembly
        assembly {
            let ptr := mload(fmp)
            for { let i := 0 } lt( i, blocks ) { i := add(1, i) } {
                let where := add(ptr, mul(32, i))
                let what := mload(add(strConfigVariableName, mul(32, i)))
                mstore(where, what)
            }
            success := staticcall(not(0), FN_NUM_GET_CONFIG_VARIABLE_UINT256, ptr, mul( blocks, 32 ), ptr, 32)
            rv := mload(ptr)
        }
        require(success, "Get config uint256 failed");
    }

    /**
     * @dev Get current BLS public key the skaled.
     */
    function _getCurrentBLSPublicKey()
        private
        view
        returns ( IFieldOperations.G2Point memory pk )
    {
        uint256 fmp = FREE_MEM_PTR;
        bool success;
        uint xa;
        uint xb;
        uint ya;
        uint yb;
        // solhint-disable-next-line no-inline-assembly
        assembly {
            let ptr := mload(fmp)
            success := staticcall(not(0), FN_NUM_GET_CURRENT_BLS_PUBLIC_KEY, ptr, 0, ptr, 128)
            xa := mload(ptr)
            xb := mload(add(ptr, 32))
            ya := mload(add(ptr, 64))
            yb := mload(add(ptr, 96))
        }
        pk.x.a = xa;
        pk.x.b = xb;
        pk.y.a = ya;
        pk.y.b = yb;
        require(success, "Get current BLS public key failed");
    }
}

exec
/bin/bash -lc "rg -n \"mainnetGasPrice|gasPriceTimestamp|setGasPrice\\(\" contracts -g '"'!contracts/test/**'"'" in /tmp/codex-sryvig8b
 succeeded in 0ms:
contracts/schain/CommunityLocker.sol:100:    uint256 public mainnetGasPrice;
contracts/schain/CommunityLocker.sol:105:    uint256 public gasPriceTimestamp;
contracts/schain/CommunityLocker.sol:244:     * @dev Set value of {mainnetGasPrice}.
contracts/schain/CommunityLocker.sol:252:    function setGasPrice(
contracts/schain/CommunityLocker.sol:260:        require(timestamp > gasPriceTimestamp, "Gas price timestamp already updated");
contracts/schain/CommunityLocker.sol:269:            mainnetGasPrice,
contracts/schain/CommunityLocker.sol:272:        mainnetGasPrice = gasPrice;
contracts/schain/CommunityLocker.sol:273:        gasPriceTimestamp = timestamp;

exec
/bin/bash -lc "sed -n '1,260p' contracts/schain/TokenManagers/TokenManagerERC20.sol" in /tmp/codex-sryvig8b
 succeeded in 0ms:
// SPDX-License-Identifier: AGPL-3.0-only

/**
 *   TokenManager.sol - SKALE Interchain Messaging Agent
 *   Copyright (C) 2019-Present SKALE Labs
 *   @author Artem Payvin
 *
 *   SKALE IMA is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published
 *   by the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   SKALE IMA is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with SKALE IMA.  If not, see <https://www.gnu.org/licenses/>.
 */

pragma solidity 0.8.27;

// cspell:words IERC20Upgradeable

import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol";
import "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC20.sol";
import {SchainHash} from "@skalenetwork/ima-interfaces/DomainTypes.sol";

import "../../Messages.sol";
import "../tokens/ERC20OnChain.sol";
import "../TokenManager.sol";


/**
 * @title TokenManagerERC20
 * @dev Runs on SKALE Chains,
 * accepts messages from mainnet,
 * and creates ERC20 clones.
 * TokenManagerERC20 mints tokens. When a user exits a SKALE chain, it burns them.
 */
contract TokenManagerERC20 is TokenManager, ITokenManagerERC20 {
    using AddressUpgradeable for address;
    using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;

    // address of ERC20 on Mainnet => ERC20 on Schain
    mapping(address => ERC20OnChain) public deprecatedClonesErc20;

    // address of clone on schain => totalSupplyOnMainnet
    mapping(IERC20Upgradeable => uint) public totalSupplyOnMainnet;

    // address clone on schain => added or not
    mapping(ERC20OnChain => bool) public addedClones;

    /// @custom:oz-retyped-from mapping(bytes32 => mapping(address => contract ERC20OnChain))
    mapping(SchainHash => mapping(address => ERC20OnChain)) public clonesErc20;

    /// @custom:oz-retyped-from mapping(bytes32 => mapping(address => uint256))
    mapping(SchainHash => mapping(address => uint256)) public transferredAmount;

    /// @custom:oz-retyped-from mapping(bytes32 => struct EnumerableSetUpgradeable.AddressSet)
    mapping(SchainHash => EnumerableSetUpgradeable.AddressSet) private _schainToERC20;

    /**
     * @dev Emitted when schain owner register new ERC20 clone.
     */
    event ERC20TokenAdded(
        SchainHash indexed chainHash,
        address indexed erc20OnMainChain,
        address indexed erc20OnSchain
    );

    /**
     * @dev Emitted when TokenManagerERC20 automatically deploys new ERC20 clone.
     */
    event ERC20TokenCreated(
        SchainHash indexed chainHash,
        address indexed erc20OnMainChain,
        address indexed erc20OnSchain
    );

    /**
     * @dev Emitted when someone sends tokens from mainnet to schain.
     */
    event ERC20TokenReceived(
        SchainHash indexed chainHash,
        address indexed erc20OnMainChain,
        address indexed erc20OnSchain,
        uint256 amount
    );

    /**
     * @dev Emitted when token is received by TokenManager and is ready to be cloned
     * or transferred on SKALE chain.
     */
    event ERC20TokenReady(SchainHash indexed chainHash, address indexed contractOnMainnet, uint256 amount);

    /**
     * @dev Move tokens from schain to mainnet.
     *
     * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {msg.sender} address.
     */
    function exitToMainERC20(
        address contractOnMainnet,
        uint256 amount
    )
        external
        override
    {
        communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);
        _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, amount);
    }

    /**
     * @dev Move tokens from schain to schain.
     *
     * {contractOnMainnet} tokens are burned on origin schain
     * and are minted on {targetSchainName} schain for {msg.sender} address.
     */
    function transferToSchainERC20(
        string calldata targetSchainName,
        address contractOnMainnet,
        uint256 amount
    )
        external
        override
    {
        transferToSchainERC20Direct(targetSchainName, contractOnMainnet, amount, msg.sender);
    }

    /**
     * @dev Allows MessageProxy to post operational message from mainnet
     * or SKALE chains.
     *
     * Requirements:
     *
     * - MessageProxy must be the sender.
     * - `fromChainHash` must exist in TokenManager addresses.
     */
    function postMessage(
        SchainHash fromChainHash,
        address sender,
        bytes calldata data
    )
        external
        override
        onlyMessageProxy
        checkReceiverChain(fromChainHash, sender)
    {
        Messages.MessageType operation = Messages.getMessageType(data);
        address receiver = address(0);
        if (
            operation == Messages.MessageType.TRANSFER_ERC20 ||
            operation == Messages.MessageType.TRANSFER_ERC20_AND_TOKEN_INFO ||
            operation == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY
        ) {
            receiver = _sendERC20(fromChainHash, data);
        } else {
            revert("MessageType is unknown");
        }
    }

    /**
     * @dev Allows Schain owner to register an ERC20 token clone in the TokenManager.
     *      Runs on destination chain.
     */
    function addERC20TokenByOwner(
        string calldata originChainName,
        address erc20OnOriginChain,
        address newErc20OnSchain
     )
        external
        override
        onlyTokenRegistrar
    {
        SchainHash originChainHash = SchainHash.wrap(keccak256(abi.encodePacked(originChainName)));
        ERC20OnChain erc20OnSchain = clonesErc20[originChainHash][erc20OnOriginChain];
        require(messageProxy.isConnectedChain(originChainName), "Chain is not connected");
        require(newErc20OnSchain.isContract(), "Given address is not a contract");
        require(ERC20OnChain(newErc20OnSchain).totalSupply() == 0, "Total supply of a new token is not zero");
        if (address(erc20OnSchain) != address(0)) {
            require(erc20OnSchain.totalSupply() == 0, "Total supply of a previous token is not zero");
        }
        require(!addedClones[ERC20OnChain(newErc20OnSchain)], "Clone was already added");
        clonesErc20[originChainHash][erc20OnOriginChain] = ERC20OnChain(newErc20OnSchain);
        addedClones[ERC20OnChain(newErc20OnSchain)] = true;
        emit ERC20TokenAdded(originChainHash, erc20OnOriginChain, newErc20OnSchain);
    }

    /**
     * @dev Is called once during contract deployment.
     */
    function initialize(
        string memory newChainName,
        IMessageProxyForSchain newMessageProxy,
        ITokenManagerLinker newIMALinker,
        ICommunityLocker newCommunityLocker,
        address newDepositBox
    )
        external
        override
    {
        TokenManager.initializeTokenManager(
            newChainName,
            newMessageProxy,
            newIMALinker,
            newCommunityLocker,
            newDepositBox
        );
    }

    /**
     * @dev Move tokens from schain to schain to specified receiver.
     *
     * {contractOnMainnet} tokens are burned on origin schain
     * and are minted on {targetSchainName} schain for {receiver} address.
     */
    function transferToSchainERC20Direct(
        string calldata targetSchainName,
        address contractOnMainnet,
        uint256 amount,
        address receiver
    )
        public
        override
    {
        SchainHash targetSchainHash = SchainHash.wrap(keccak256(abi.encodePacked(targetSchainName)));
        transferToSchainHashERC20Direct(targetSchainHash, contractOnMainnet, amount, receiver);
    }

    /**
     * @dev Move tokens from schain to schain to specified receiver.
     *
     * {contractOnMainnet} tokens are burned on origin schain
     * and are minted on {targetSchainHash} schain for {receiver} address.
     */
    function transferToSchainHashERC20Direct(
        SchainHash targetSchainHash,
        address contractOnMainnet,
        uint256 amount,
        address receiver
    )
        public
        override
        onlySchainTarget(targetSchainHash, receiver)
    {
        communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);
        _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, receiver, amount);
    }

    // private

    /**
     * @dev Allows TokenManager to send ERC20 tokens.
     *
     * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.
     * Emits a {ERC20TokenReceived} event on success.
     */

exec
/bin/bash -lc "sed -n '261,520p' contracts/schain/TokenManagers/TokenManagerERC20.sol" in /tmp/codex-sryvig8b
 succeeded in 0ms:
    function _sendERC20(SchainHash fromChainHash, bytes calldata data) private returns (address) {
        Messages.MessageType messageType = Messages.getMessageType(data);
        (address receiver, address token, uint256 amount) = _decodeErc20Message(data);
        ERC20OnChain contractOnSchain;
        if (messageType != Messages.MessageType.TRANSFER_ERC20) {
            uint256 totalSupply;
            if (messageType == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY) {
                Messages.TransferErc20AndTotalSupplyMessage memory message =
                    Messages.decodeTransferErc20AndTotalSupplyMessage(data);
                totalSupply = message.totalSupply;
                contractOnSchain = clonesErc20[fromChainHash][token];
            } else {
                Messages.TransferErc20AndTokenInfoMessage memory message =
                    Messages.decodeTransferErc20AndTokenInfoMessage(data);
                totalSupply = message.totalSupply;
                contractOnSchain = clonesErc20[fromChainHash][token];

                if (address(contractOnSchain) == address(0)) {
                    require(automaticDeploy, "Automatic deploy is disabled");
                    contractOnSchain = new ERC20OnChain(message.tokenInfo.name, message.tokenInfo.symbol);
                    clonesErc20[fromChainHash][token] = contractOnSchain;
                    addedClones[contractOnSchain] = true;
                    emit ERC20TokenCreated(fromChainHash, token, address(contractOnSchain));
                }
            }
            if (totalSupply != totalSupplyOnMainnet[contractOnSchain]) {
                totalSupplyOnMainnet[contractOnSchain] = totalSupply;
            }
            bool noOverflow;
            uint updatedTotalSupply;
            (noOverflow, updatedTotalSupply) = SafeMathUpgradeable.tryAdd(contractOnSchain.totalSupply(), amount);
            require(
                noOverflow && updatedTotalSupply <= totalSupplyOnMainnet[contractOnSchain],
                "Total supply exceeded"
            );
            contractOnSchain.mint(receiver, amount);
        } else {
            require(token.isContract() && _schainToERC20[fromChainHash].contains(token), "Incorrect main chain token");
            require(ERC20Upgradeable(token).balanceOf(address(this)) >= amount, "Not enough money");
            _removeTransferredAmount(fromChainHash, token, amount);
            require(
                ERC20Upgradeable(token).transfer(receiver, amount),
                "Transfer was failed"
            );
        }
        emit ERC20TokenReceived(fromChainHash, token, address(contractOnSchain), amount);
        messageProxy.topUpReceiverBalance(payable(receiver));
        return receiver;
    }

    /**
     * @dev Burn tokens on schain and send message to unlock them on target chain.
     */
    function _exit(
        SchainHash chainHash,
        address messageReceiver,
        address contractOnMainChain,
        address to,
        uint256 amount
    )
        private
    {
        bool isMainChainToken;
        ERC20OnChain contractOnSchain = clonesErc20[chainHash][contractOnMainChain];
        if (address(contractOnSchain) == address(0)) {
            contractOnSchain = ERC20OnChain(contractOnMainChain);
            require(!addedClones[contractOnSchain], "Incorrect main chain token");
            isMainChainToken = true;
        }
        require(address(contractOnSchain).isContract(), "No token clone on schain");
        require(contractOnSchain.balanceOf(msg.sender) >= amount, "Insufficient funds");
        require(
            contractOnSchain.allowance(
                msg.sender,
                address(this)
            ) >= amount,
            "Transfer is not approved by token holder"
        );
        bytes memory data = Messages.encodeTransferErc20Message(address(contractOnMainChain), to, amount);
        if (isMainChainToken) {
            require(chainHash != MAINNET_HASH, "Main chain token could not be transferred to Mainnet");
            data = _receiveERC20(
                chainHash,
                address(contractOnSchain),
                to,
                amount
            );
            _saveTransferredAmount(chainHash, address(contractOnSchain), amount);
            require(
                contractOnSchain.transferFrom(msg.sender, address(this), amount),
                "Transfer was failed"
            );
        } else {
            require(
                contractOnSchain.transferFrom(msg.sender, address(this), amount),
                "Transfer was failed"
            );
            contractOnSchain.burn(amount);
        }
        messageProxy.postOutgoingMessage(
            chainHash,
            messageReceiver,
            data
        );
    }

    /**
     * @dev Saves amount of tokens that was transferred to schain.
     */
    function _saveTransferredAmount(SchainHash chainHash, address erc20Token, uint256 amount) private {
        transferredAmount[chainHash][erc20Token] += amount;
    }

    /**
     * @dev Removes amount of tokens that was transferred from schain.
     */
    function _removeTransferredAmount(SchainHash chainHash, address erc20Token, uint256 amount) private {
        transferredAmount[chainHash][erc20Token] -= amount;
    }

    /**
     * @dev Allows DepositBoxERC20 to receive ERC20 tokens.
     *
     * Emits an {ERC20TokenReady} event.
     *
     * Requirements:
     *
     * - Amount must be less than or equal to the total supply of the ERC20 contract.
     * - Whitelist should be turned off for auto adding tokens to DepositBoxERC20.
     */
    function _receiveERC20(
        SchainHash chainHash,
        address erc20OnMainChain,
        address to,
        uint256 amount
    )
        private
        returns (bytes memory data)
    {
        ERC20BurnableUpgradeable erc20 = ERC20BurnableUpgradeable(erc20OnMainChain);
        uint256 totalSupply = erc20.totalSupply();
        require(amount <= totalSupply, "Amount is incorrect");
        bool isERC20AddedToSchain = _schainToERC20[chainHash].contains(erc20OnMainChain);
        if (!isERC20AddedToSchain) {
            _addERC20ForSchain(chainHash, erc20OnMainChain);
            data = Messages.encodeTransferErc20AndTokenInfoMessage(
                erc20OnMainChain,
                to,
                amount,
                _getErc20TotalSupply(erc20),
                _getErc20TokenInfo(erc20)
            );
        } else {
            data = Messages.encodeTransferErc20AndTotalSupplyMessage(
                erc20OnMainChain,
                to,
                amount,
                _getErc20TotalSupply(erc20)
            );
        }
        emit ERC20TokenReady(chainHash, erc20OnMainChain, amount);
    }

    /**
     * @dev Adds an ERC20 token to DepositBoxERC20.
     *
     * Emits an {ERC20TokenAdded} event.
     *
     * Requirements:
     *
     * - Given address should be contract.
     */
    function _addERC20ForSchain(SchainHash chainHash, address erc20OnMainChain) private {
        require(erc20OnMainChain.isContract(), "Given address is not a contract");
        require(!_schainToERC20[chainHash].contains(erc20OnMainChain), "ERC20 Token was already added");
        _schainToERC20[chainHash].add(erc20OnMainChain);
        emit ERC20TokenAdded(chainHash, erc20OnMainChain, address(0));
    }

    /**
     * @dev Returns total supply of ERC20 token.
     */
    function _getErc20TotalSupply(ERC20Upgradeable erc20Token) private view returns (uint256) {
        return erc20Token.totalSupply();
    }

    /**
     * @dev Returns info about ERC20 token such as token name, decimals, symbol.
     */
    function _getErc20TokenInfo(ERC20Upgradeable erc20Token) private view returns (Messages.Erc20TokenInfo memory) {
        return Messages.Erc20TokenInfo({
            name: erc20Token.name(),
            decimals: erc20Token.decimals(),
            symbol: erc20Token.symbol()
        });
    }


    /**
     * @dev Decodes ERC20 transfer message depending on type of message.
     */
    function _decodeErc20Message(bytes calldata data)
        private
        pure
        returns (address, address, uint256)
    {
        Messages.MessageType messageType = Messages.getMessageType(data);
        if (messageType == Messages.MessageType.TRANSFER_ERC20) {
            Messages.TransferErc20Message memory message =
                Messages.decodeTransferErc20Message(data);
            return (
                message.receiver,
                message.token,
                message.amount
            );
        } else if (messageType == Messages.MessageType.TRANSFER_ERC20_AND_TOTAL_SUPPLY) {
            Messages.TransferErc20AndTotalSupplyMessage memory messageTotalSupply =
                Messages.decodeTransferErc20AndTotalSupplyMessage(data);
            return (
                messageTotalSupply.baseErc20transfer.receiver,
                messageTotalSupply.baseErc20transfer.token,
                messageTotalSupply.baseErc20transfer.amount
            );
        } else {
            Messages.TransferErc20AndTokenInfoMessage memory messageTokenInfo =
                Messages.decodeTransferErc20AndTokenInfoMessage(data);
            return (
                messageTokenInfo.baseErc20transfer.receiver,
                messageTokenInfo.baseErc20transfer.token,
                messageTokenInfo.baseErc20transfer.amount
            );
        }
    }
}

exec
/bin/bash -lc "sed -n '1,280p' contracts/schain/TokenManagers/TokenManagerEth.sol" in /tmp/codex-sryvig8b
 succeeded in 0ms:
// SPDX-License-Identifier: AGPL-3.0-only

/**
 *   TokenManager.sol - SKALE Interchain Messaging Agent
 *   Copyright (C) 2019-Present SKALE Labs
 *   @author Artem Payvin
 *
 *   SKALE IMA is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published
 *   by the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   SKALE IMA is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with SKALE IMA.  If not, see <https://www.gnu.org/licenses/>.
 */

pragma solidity 0.8.27;

import {SchainHash} from "@skalenetwork/ima-interfaces/DomainTypes.sol";
import "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerEth.sol";

import "../../Messages.sol";
import "../TokenManager.sol";


/**
 * @title TokenManagerEth
 * @dev Runs on SKALE Chains and
 * accepts messages from mainnet.
 * TokenManagerEth mints EthErc20 tokens. When a user exits a SKALE chain, it burns them.
 */
contract TokenManagerEth is TokenManager, ITokenManagerEth {

    IEthErc20 public ethErc20;

    /// Create a new token manager

    /**
     * @dev Register EthErc20 token.
     */
    function setEthErc20Address(IEthErc20 newEthErc20Address) external override {
        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "Not authorized caller");
        require(ethErc20 != newEthErc20Address, "Must be new address");
        ethErc20 = newEthErc20Address;
    }

    /**
     * @dev Move ETH from schain to mainnet.
     *
     * EthErc20 tokens are burned on schain and ETH are unlocked on mainnet for {to} address.
     */
    function exitToMain(uint256 amount) external override {
        communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);
        _exit(MAINNET_HASH, depositBox, msg.sender, amount);
    }

    /**
     * @dev Allows MessageProxy to post operational message from mainnet
     * or SKALE chains.
     *
     * Requirements:
     *
     * - MessageProxy must be the sender.
     * - `fromChainHash` must exist in TokenManager addresses.
     */
    function postMessage(
        SchainHash fromChainHash,
        address sender,
        bytes calldata data
    )
        external
        override
        onlyMessageProxy
        checkReceiverChain(fromChainHash, sender)
    {
        Messages.TransferEthMessage memory decodedMessage = Messages.decodeTransferEthMessage(data);
        address receiver = decodedMessage.receiver;
        require(receiver != address(0), "Incorrect receiver");
        ethErc20.mint(receiver, decodedMessage.amount);
        messageProxy.topUpReceiverBalance(payable(receiver));
    }

    /**
     * @dev Is called once during contract deployment.
     */
    function initialize(
        string memory newChainName,
        IMessageProxyForSchain newMessageProxy,
        ITokenManagerLinker newIMALinker,
        ICommunityLocker newCommunityLocker,
        address newDepositBox,
        IEthErc20 ethErc20Address
    )
        external
        override
        initializer
    {
        TokenManager.initializeTokenManager(
            newChainName,
            newMessageProxy,
            newIMALinker,
            newCommunityLocker,
            newDepositBox
        );
        ethErc20 = ethErc20Address;
    }

    // private

    /**
     * @dev Checks whether sender contract is DepositBox.
     */
    function _checkSender(SchainHash fromChainHash, address sender) internal view override returns (bool) {
        return fromChainHash == MAINNET_HASH && sender == depositBox;
    }

    /**
     * @dev Burn EthErc20 tokens on schain and send message to unlock ETH on target chain.
     */
    function _exit(
        SchainHash chainHash,
        address messageReceiver,
        address to,
        uint256 amount
    )
        private
    {
        if (amount > 0) {
            ethErc20.forceBurn(msg.sender, amount);
        }
        bytes memory data = Messages.encodeTransferEthMessage(to, amount);
        messageProxy.postOutgoingMessage(
            chainHash,
            messageReceiver,
            data
        );
    }
}

exec
/bin/bash -lc "sed -n '1,420p' contracts/schain/TokenManagers/TokenManagerERC721.sol" in /tmp/codex-sryvig8b
 succeeded in 0ms:
// SPDX-License-Identifier: AGPL-3.0-only

/**
 *   TokenManager.sol - SKALE Interchain Messaging Agent
 *   Copyright (C) 2019-Present SKALE Labs
 *   @author Artem Payvin
 *
 *   SKALE IMA is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published
 *   by the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   SKALE IMA is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with SKALE IMA.  If not, see <https://www.gnu.org/licenses/>.
 */

pragma solidity 0.8.27;

import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
import "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC721.sol";

import "../../Messages.sol";
import "../tokens/ERC721OnChain.sol";
import "../TokenManager.sol";


/**
 * @title TokenManagerERC721
 * @dev Runs on SKALE Chains,
 * accepts messages from mainnet,
 * and creates ERC721 clones.
 * TokenManagerERC721 mints tokens. When a user exits a SKALE chain, it burns them.
 */
contract TokenManagerERC721 is TokenManager, ITokenManagerERC721 {
    using AddressUpgradeable for address;
    using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;

    // address of ERC721 on Mainnet => ERC721 on Schain
    mapping(address => ERC721OnChain) public deprecatedClonesErc721;

    // address clone on schain => added or not
    mapping(ERC721OnChain => bool) public addedClones;

    /// @custom:oz-retyped-from mapping(bytes32 => mapping(address => contract ERC721OnChain))
    mapping(SchainHash => mapping(address => ERC721OnChain)) public clonesErc721;

    /// @custom:oz-retyped-from mapping(address => mapping(uint256 => bytes32))
    mapping(address => mapping(uint256 => SchainHash)) public transferredAmount;

    /// @custom:oz-retyped-from mapping(bytes32 => struct EnumerableSetUpgradeable.AddressSet)
    mapping(SchainHash => EnumerableSetUpgradeable.AddressSet) private _schainToERC721;

    /**
     * @dev Emitted when schain owner register new ERC721 clone.
     */
    event ERC721TokenAdded(
        SchainHash indexed chainHash,
        address indexed erc721OnMainChain,
        address indexed erc721OnSchain
    );

    /**
     * @dev Emitted when TokenManagerERC721 automatically deploys new ERC721 clone.
     */
    event ERC721TokenCreated(
        SchainHash indexed chainHash,
        address indexed erc721OnMainChain,
        address indexed erc721OnSchain
    );

    /**
     * @dev Emitted when someone sends tokens from mainnet to schain.
     */
    event ERC721TokenReceived(
        SchainHash indexed chainHash,
        address indexed erc721OnMainChain,
        address indexed erc721OnSchain,
        uint256 tokenId
    );

    /**
     * @dev Emitted when token is received by TokenManager and is ready to be cloned
     * or transferred on SKALE chain.
     */
    event ERC721TokenReady(SchainHash indexed chainHash, address indexed contractOnMainnet, uint256 tokenId);

    /**
     * @dev Move tokens from schain to mainnet.
     *
     * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {msg.sender} address.
     */
    function exitToMainERC721(
        address contractOnMainnet,
        uint256 tokenId
    )
        external
        override
    {
        communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);
        _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, tokenId);
    }

    /**
     * @dev Move tokens from schain to schain.
     *
     * {contractOnMainnet} tokens are burned on origin schain
     * and are minted on {targetSchainName} schain for {msg.sender} address.
     */
    function transferToSchainERC721(
        string calldata targetSchainName,
        address contractOnMainnet,
        uint256 tokenId
    )
        external
        override
        rightTransaction(targetSchainName, msg.sender)
    {
        SchainHash targetSchainHash = SchainHash.wrap(keccak256(abi.encodePacked(targetSchainName)));
        communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);
        _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, tokenId);
    }

    /**
     * @dev Allows MessageProxy to post operational message from mainnet
     * or SKALE chains.
     *
     * Requirements:
     *
     * - MessageProxy must be the sender.
     * - `fromChainHash` must exist in TokenManager addresses.
     */
    function postMessage(
        SchainHash fromChainHash,
        address sender,
        bytes calldata data
    )
        external
        virtual
        override
        onlyMessageProxy
        checkReceiverChain(fromChainHash, sender)
    {
        Messages.MessageType operation = Messages.getMessageType(data);
        address receiver = address(0);
        if (
            operation == Messages.MessageType.TRANSFER_ERC721_AND_TOKEN_INFO ||
            operation == Messages.MessageType.TRANSFER_ERC721
        ) {
            receiver = _sendERC721(fromChainHash, data);
        } else {
            revert("MessageType is unknown");
        }
    }

    /**
     * @dev Allows Schain owner to register an ERC721 token clone in the token manager.
     */
    function addERC721TokenByOwner(
        string calldata originChainName,
        address erc721OnOriginChain,
        address newErc721OnSchain
    )
        external
        override
        onlyTokenRegistrar
    {
        SchainHash originChainHash = SchainHash.wrap(keccak256(abi.encodePacked(originChainName)));
        require(messageProxy.isConnectedChain(originChainName), "Chain is not connected");
        require(newErc721OnSchain.isContract(), "Given address is not a contract");
        require(address(clonesErc721[originChainHash][erc721OnOriginChain]) == address(0), "Could not relink clone");
        require(!addedClones[ERC721OnChain(newErc721OnSchain)], "Clone was already added");
        clonesErc721[originChainHash][erc721OnOriginChain] = ERC721OnChain(newErc721OnSchain);
        addedClones[ERC721OnChain(newErc721OnSchain)] = true;
        emit ERC721TokenAdded(originChainHash, erc721OnOriginChain, newErc721OnSchain);
    }

    /**
     * @dev Is called once during contract deployment.
     */
    function initialize(
        string memory newChainName,
        IMessageProxyForSchain newMessageProxy,
        ITokenManagerLinker newIMALinker,
        ICommunityLocker newCommunityLocker,
        address newDepositBox
    )
        external
        override
    {
        TokenManager.initializeTokenManager(
            newChainName,
            newMessageProxy,
            newIMALinker,
            newCommunityLocker,
            newDepositBox
        );
    }

    // private

    /**
     * @dev Allows TokenManager to send ERC721 tokens.
     *
     * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.
     * Emits a {ERC20TokenReceived} event on success.
     */
    function _sendERC721(SchainHash fromChainHash, bytes calldata data) internal virtual returns (address) {
        Messages.MessageType messageType = Messages.getMessageType(data);
        address receiver;
        address token;
        uint256 tokenId;
        ERC721OnChain contractOnSchain;
        if (messageType == Messages.MessageType.TRANSFER_ERC721) {
            Messages.TransferErc721Message memory message = Messages.decodeTransferErc721Message(data);
            receiver = message.receiver;
            token = message.token;
            tokenId = message.tokenId;
            contractOnSchain = clonesErc721[fromChainHash][token];
        } else {
            Messages.TransferErc721AndTokenInfoMessage memory message =
                Messages.decodeTransferErc721AndTokenInfoMessage(data);
            receiver = message.baseErc721transfer.receiver;
            token = message.baseErc721transfer.token;
            tokenId = message.baseErc721transfer.tokenId;
            contractOnSchain = clonesErc721[fromChainHash][token];
            if (address(contractOnSchain) == address(0)) {
                require(automaticDeploy, "Automatic deploy is disabled");
                contractOnSchain = new ERC721OnChain(message.tokenInfo.name, message.tokenInfo.symbol);
                clonesErc721[fromChainHash][token] = contractOnSchain;
                addedClones[contractOnSchain] = true;
                emit ERC721TokenCreated(fromChainHash, token, address(contractOnSchain));
            }
        }
        if (
            messageType == Messages.MessageType.TRANSFER_ERC721 &&
            fromChainHash != MAINNET_HASH &&
            _schainToERC721[fromChainHash].contains(token)
        ) {
            require(token.isContract(), "Incorrect main chain token");
            require(IERC721Upgradeable(token).ownerOf(tokenId) == address(this), "Incorrect tokenId");
            _removeTransferredAmount(fromChainHash, token, tokenId);
            IERC721Upgradeable(token).transferFrom(address(this), receiver, tokenId);
        } else {
            contractOnSchain.mint(receiver, tokenId);
        }
        emit ERC721TokenReceived(fromChainHash, token, address(contractOnSchain), tokenId);
        messageProxy.topUpReceiverBalance(payable(receiver));
        return receiver;
    }

    /**
     * @dev Removes the ids of tokens that was transferred from schain.
     */
    function _removeTransferredAmount(SchainHash chainHash, address erc721Token, uint256 tokenId) internal {
        require(transferredAmount[erc721Token][tokenId] == chainHash, "Token was already transferred from chain");
        transferredAmount[erc721Token][tokenId] = SchainHash.wrap(bytes32(0));
    }

    /**
     * @dev Allows DepositBoxERC721 to receive ERC721 tokens.
     *
     * Emits an {ERC721TokenReady} event.
     *
     * Requirements:
     *
     * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.
     */
    function _receiveERC721(
        SchainHash chainHash,
        address erc721OnMainChain,
        address to,
        uint256 tokenId
    )
        internal
        virtual
        returns (bytes memory data)
    {
        bool isERC721AddedToSchain = _schainToERC721[chainHash].contains(erc721OnMainChain);
        if (!isERC721AddedToSchain) {
            _addERC721ForSchain(chainHash, erc721OnMainChain);
            data = Messages.encodeTransferErc721AndTokenInfoMessage(
                erc721OnMainChain,
                to,
                tokenId,
                _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainChain))
            );
        } else {
            data = Messages.encodeTransferErc721Message(erc721OnMainChain, to, tokenId);
        }
        emit ERC721TokenReady(chainHash, erc721OnMainChain, tokenId);
    }

    /**
     * @dev Adds an ERC721 token to DepositBoxERC721.
     *
     * Emits an {ERC721TokenAdded} event.
     *
     * Requirements:
     *
     * - Given address should be contract.
     */
    function _addERC721ForSchain(SchainHash chainHash, address erc721OnMainChain) internal {
        require(erc721OnMainChain.isContract(), "Given address is not a contract");
        require(!_schainToERC721[chainHash].contains(erc721OnMainChain), "ERC721 Token was already added");
        _schainToERC721[chainHash].add(erc721OnMainChain);
        emit ERC721TokenAdded(chainHash, erc721OnMainChain, address(0));
    }

    /**
     * @dev Burn tokens on schain and send message to unlock them on target chain.
     */
    function _exit(
        SchainHash chainHash,
        address messageReceiver,
        address contractOnMainChain,
        address to,
        uint256 tokenId
    )
        internal
        virtual
    {
        bool isMainChainToken;
        ERC721OnChain contractOnSchain = clonesErc721[chainHash][contractOnMainChain];
        if (address(contractOnSchain) == address(0)) {
            contractOnSchain = ERC721OnChain(contractOnMainChain);
            require(!addedClones[contractOnSchain], "Incorrect main chain token");
            isMainChainToken = true;
        }
        require(address(contractOnSchain).isContract(), "No token clone on schain");
        require(contractOnSchain.getApproved(tokenId) == address(this), "Not allowed ERC721 Token");
        bytes memory data = Messages.encodeTransferErc721Message(contractOnMainChain, to, tokenId);
        if (isMainChainToken) {
            require(chainHash != MAINNET_HASH, "Main chain token could not be transfered to Mainnet");
            data = _receiveERC721(
                chainHash,
                address(contractOnSchain),
                msg.sender,
                tokenId
            );
            _saveTransferredAmount(chainHash, address(contractOnSchain), tokenId);
            contractOnSchain.transferFrom(msg.sender, address(this), tokenId);
        } else {
            contractOnSchain.transferFrom(msg.sender, address(this), tokenId);
            contractOnSchain.burn(tokenId);
        }
        messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);
    }

    /**
     * @dev Saves the ids of tokens that was transferred to schain.
     */
    function _saveTransferredAmount(SchainHash chainHash, address erc721Token, uint256 tokenId) internal {
        require(
            transferredAmount[erc721Token][tokenId] == SchainHash.wrap(bytes32(0)),
            "Token was already transferred to chain"
        );
        transferredAmount[erc721Token][tokenId] = chainHash;
    }

    /**
     * @dev Returns info about ERC721 token such as token name, symbol.
     */
    function _getTokenInfo(IERC721MetadataUpgradeable erc721) internal view returns (Messages.Erc721TokenInfo memory) {
        return Messages.Erc721TokenInfo({
            name: erc721.name(),
            symbol: erc721.symbol()
        });
    }

    function _isERC721AddedToSchain(SchainHash chainHash, address erc721OnMainChain) internal view returns (bool) {
        return _schainToERC721[chainHash].contains(erc721OnMainChain);
    }
}

exec
/bin/bash -lc "sed -n '1,260p' contracts/schain/TokenManagers/TokenManagerERC721WithMetadata.sol" in /tmp/codex-sryvig8b
 succeeded in 0ms:
// SPDX-License-Identifier: AGPL-3.0-only

/**
 *   TokenManagerERC721WithMetadata.sol - SKALE Interchain Messaging Agent
 *   Copyright (C) 2021-Present SKALE Labs
 *   @author Artem Payvin
 *
 *   SKALE IMA is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published
 *   by the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   SKALE IMA is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with SKALE IMA.  If not, see <https://www.gnu.org/licenses/>.
 */

pragma solidity 0.8.27;

import "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";

import "./TokenManagerERC721.sol";
import "../../Messages.sol";


/**
 * @title TokenManagerERC721WithMetadata
 * @dev Runs on SKALE Chains,
 * accepts messages from mainnet,
 * and creates ERC721 clones.
 * TokenManagerERC721 mints tokens. When a user exits a SKALE chain, it burns them.
 */
contract TokenManagerERC721WithMetadata is TokenManagerERC721 {
    using AddressUpgradeable for address;

    /**
     * @dev Allows MessageProxy to post operational message from mainnet
     * or SKALE chains.
     *
     * Requirements:
     *
     * - MessageProxy must be the sender.
     * - `fromChainHash` must exist in TokenManager addresses.
     */
    function postMessage(
        SchainHash fromChainHash,
        address sender,
        bytes calldata data
    )
        external
        override
        onlyMessageProxy
        checkReceiverChain(fromChainHash, sender)
    {
        Messages.MessageType operation = Messages.getMessageType(data);
        address receiver = address(0);
        if (
            operation == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA_AND_TOKEN_INFO ||
            operation == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA
        ) {
            receiver = _sendERC721(fromChainHash, data);
        } else {
            revert("MessageType is unknown");
        }
    }

    /**
     * @dev Allows TokenManager to send ERC721 tokens.
     *
     * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.
     * Emits a {ERC20TokenReceived} event on success.
     */
    function _sendERC721(SchainHash fromChainHash, bytes calldata data) internal override returns (address) {
        Messages.MessageType messageType = Messages.getMessageType(data);
        address receiver;
        address token;
        uint256 tokenId;
        string memory tokenURI;
        ERC721OnChain contractOnSchain;
        if (messageType == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA) {
            Messages.TransferErc721MessageWithMetadata memory message =
                Messages.decodeTransferErc721MessageWithMetadata(data);
            receiver = message.erc721message.receiver;
            token = message.erc721message.token;
            tokenId = message.erc721message.tokenId;
            tokenURI = message.tokenURI;
            contractOnSchain = clonesErc721[fromChainHash][token];
        } else {
            Messages.TransferErc721WithMetadataAndTokenInfoMessage memory message =
                Messages.decodeTransferErc721WithMetadataAndTokenInfoMessage(data);
            receiver = message.baseErc721transferWithMetadata.erc721message.receiver;
            token = message.baseErc721transferWithMetadata.erc721message.token;
            tokenId = message.baseErc721transferWithMetadata.erc721message.tokenId;
            tokenURI = message.baseErc721transferWithMetadata.tokenURI;
            contractOnSchain = clonesErc721[fromChainHash][token];
            if (address(contractOnSchain) == address(0)) {
                require(automaticDeploy, "Automatic deploy is disabled");
                contractOnSchain = new ERC721OnChain(message.tokenInfo.name, message.tokenInfo.symbol);
                clonesErc721[fromChainHash][token] = contractOnSchain;
                addedClones[contractOnSchain] = true;
                emit ERC721TokenCreated(fromChainHash, token, address(contractOnSchain));
            }
        }
        if (
            messageType == Messages.MessageType.TRANSFER_ERC721_WITH_METADATA &&
            fromChainHash != MAINNET_HASH &&
            _isERC721AddedToSchain(fromChainHash, token)
        ) {
            require(token.isContract(), "Incorrect main chain token");
            require(IERC721Upgradeable(token).ownerOf(tokenId) == address(this), "Incorrect tokenId");
            _removeTransferredAmount(fromChainHash, token, tokenId);
            IERC721Upgradeable(token).transferFrom(address(this), receiver, tokenId);
        } else {
            contractOnSchain.mint(receiver, tokenId);
            contractOnSchain.setTokenURI(tokenId, tokenURI);
        }
        emit ERC721TokenReceived(fromChainHash, token, address(contractOnSchain), tokenId);
        messageProxy.topUpReceiverBalance(payable(receiver));
        return receiver;
    }

    /**
     * @dev Burn tokens on schain and send message to unlock them on target chain.
     */
    function _exit(
        SchainHash chainHash,
        address messageReceiver,
        address contractOnMainChain,
        address to,
        uint256 tokenId
    )
        internal
        override
    {
        bool isMainChainToken;
        ERC721OnChain contractOnSchain = clonesErc721[chainHash][contractOnMainChain];
        if (address(contractOnSchain) == address(0)) {
            contractOnSchain = ERC721OnChain(contractOnMainChain);
            require(!addedClones[contractOnSchain], "Incorrect main chain token");
            isMainChainToken = true;
        }
        require(address(contractOnSchain).isContract(), "No token clone on schain");
        require(contractOnSchain.getApproved(tokenId) == address(this), "Not allowed ERC721 Token");
        bytes memory data = Messages.encodeTransferErc721MessageWithMetadata(
            contractOnMainChain,
            to,
            tokenId,
            _getTokenURI(IERC721MetadataUpgradeable(contractOnSchain), tokenId)
        );
        if (isMainChainToken) {
            require(chainHash != MAINNET_HASH, "Main chain token could not be transfered to Mainnet");
            data = _receiveERC721(
                chainHash,
                address(contractOnSchain),
                msg.sender,
                tokenId
            );
            _saveTransferredAmount(chainHash, address(contractOnSchain), tokenId);
            contractOnSchain.transferFrom(msg.sender, address(this), tokenId);
        } else {
            contractOnSchain.transferFrom(msg.sender, address(this), tokenId);
            contractOnSchain.burn(tokenId);
        }
        messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);
    }

    /**
     * @dev Allows DepositBoxERC721 to receive ERC721 tokens.
     *
     * Emits an {ERC721TokenReady} event.
     *
     * Requirements:
     *
     * - Whitelist should be turned off for auto adding tokens to DepositBoxERC721.
     */
    function _receiveERC721(
        SchainHash chainHash,
        address erc721OnMainChain,
        address to,
        uint256 tokenId
    )
        internal
        override
        returns (bytes memory data)
    {
        bool isERC721AddedToSchain = _isERC721AddedToSchain(chainHash, erc721OnMainChain);
        if (!isERC721AddedToSchain) {
            _addERC721ForSchain(chainHash, erc721OnMainChain);
            data = Messages.encodeTransferErc721WithMetadataAndTokenInfoMessage(
                erc721OnMainChain,
                to,
                tokenId,
                _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainChain), tokenId),
                _getTokenInfo(IERC721MetadataUpgradeable(erc721OnMainChain))
            );
        } else {
            data = Messages.encodeTransferErc721MessageWithMetadata(
                erc721OnMainChain,
                to,
                tokenId,
                _getTokenURI(IERC721MetadataUpgradeable(erc721OnMainChain), tokenId)
            );
        }
        emit ERC721TokenReady(chainHash, erc721OnMainChain, tokenId);
    }

    /**
     * @dev Returns tokenURI of ERC721 token.
     */
    function _getTokenURI(IERC721MetadataUpgradeable erc721, uint256 tokenId) private view returns (string memory) {
        return erc721.tokenURI(tokenId);
    }

}

exec
/bin/bash -lc "sed -n '1,700p' contracts/schain/TokenManagers/TokenManagerERC1155.sol" in /tmp/codex-sryvig8b
 succeeded in 0ms:
// SPDX-License-Identifier: AGPL-3.0-only

/**
 *   TokenManager.sol - SKALE Interchain Messaging Agent
 *   Copyright (C) 2019-Present SKALE Labs
 *   @author Artem Payvin
 *
 *   SKALE IMA is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published
 *   by the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   SKALE IMA is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with SKALE IMA.  If not, see <https://www.gnu.org/licenses/>.
 */

pragma solidity 0.8.27;

import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
import "@skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC1155.sol";

import "../../Messages.sol";
import "../tokens/ERC1155OnChain.sol";
import "../TokenManager.sol";
import "../../thirdparty/ERC1155ReceiverUpgradeableWithoutGap.sol";


/**
 * @title TokenManagerERC1155
 * @dev Runs on SKALE Chains,
 * accepts messages from mainnet,
 * and creates ERC1155 clones.
 * TokenManagerERC1155 mints tokens. When a user exits a SKALE chain, it burns them.
 */
contract TokenManagerERC1155 is
    TokenManager,
    ERC1155ReceiverUpgradeableWithoutGap,
    ITokenManagerERC1155
{
    using AddressUpgradeable for address;
    using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;

    // address of ERC1155 on Mainnet => ERC1155 on Schain
    mapping(address => ERC1155OnChain) public deprecatedClonesErc1155;

    // address clone on schain => added or not
    mapping(ERC1155OnChain => bool) public addedClones;

    /// @custom:oz-retyped-from mapping(bytes32 => mapping(address => contract ERC1155OnChain))
    mapping(SchainHash => mapping(address => ERC1155OnChain)) public clonesErc1155;

    /// @custom:oz-retyped-from mapping(bytes32 => mapping(address => mapping(uint256 => uint256)))
    mapping(SchainHash => mapping(address => mapping(uint256 => uint256))) public transferredAmount;

    /// @custom:oz-retyped-from mapping(bytes32 => struct EnumerableSetUpgradeable.AddressSet)
    mapping(SchainHash => EnumerableSetUpgradeable.AddressSet) private _schainToERC1155;

    /**
     * @dev Emitted when schain owner register new ERC1155 clone.
     */
    event ERC1155TokenAdded(
        SchainHash indexed chainHash,
        address indexed erc1155OnMainnet,
        address indexed erc1155OnSchain
    );

    /**
     * @dev Emitted when TokenManagerERC1155 automatically deploys new ERC1155 clone.
     */
    event ERC1155TokenCreated(
        SchainHash indexed chainHash,
        address indexed erc1155OnMainnet,
        address indexed erc1155OnSchain
    );

    /**
     * @dev Emitted when someone sends tokens from mainnet to schain.
     */
    event ERC1155TokenReceived(
        SchainHash indexed chainHash,
        address indexed erc1155OnMainnet,
        address indexed erc1155OnSchain,
        uint256[] ids,
        uint256[] amounts
    );

    /**
     * @dev Emitted when token is received by TokenManager and is ready to be cloned
     * or transferred on SKALE chain.
     */
    event ERC1155TokenReady(
        SchainHash indexed chainHash,
        address indexed contractOnMainnet,
        uint256[] ids,
        uint256[] amounts
    );

    /**
     * @dev Move tokens from schain to mainnet.
     *
     * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {to} address.
     */
    function exitToMainERC1155(
        address contractOnMainnet,
        uint256 id,
        uint256 amount
    )
        external
        override
    {
        communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);
        _exit(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, id, amount);
    }

    /**
     * @dev Move batch of tokens from schain to mainnet.
     *
     * {contractOnMainnet} tokens are burned on schain and unlocked on mainnet for {to} address.
     */
    function exitToMainERC1155Batch(
        address contractOnMainnet,
        uint256[] calldata ids,
        uint256[] calldata amounts
    )
        external
        override
    {
        communityLocker.checkAllowedToSendMessage(MAINNET_HASH, msg.sender);
        _exitBatch(MAINNET_HASH, depositBox, contractOnMainnet, msg.sender, ids, amounts);
    }

    /**
     * @dev Move tokens from schain to schain.
     *
     * {contractOnMainnet} tokens are burned on origin schain
     * and are minted on {targetSchainName} schain for {to} address.
     */
    function transferToSchainERC1155(
        string calldata targetSchainName,
        address contractOnMainnet,
        uint256 id,
        uint256 amount
    )
        external
        override
        rightTransaction(targetSchainName, msg.sender)
    {
        SchainHash targetSchainHash = SchainHash.wrap(keccak256(abi.encodePacked(targetSchainName)));
        communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);
        _exit(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, id, amount);
    }

    /**
     * @dev Move batch of tokens from schain to schain.
     *
     * {contractOnMainnet} tokens are burned on origin schain
     * and are minted on {targetSchainName} schain for {to} address.
     */
    function transferToSchainERC1155Batch(
        string calldata targetSchainName,
        address contractOnMainnet,
        uint256[] calldata ids,
        uint256[] calldata amounts
    )
        external
        override
        rightTransaction(targetSchainName, msg.sender)
    {
        SchainHash targetSchainHash = SchainHash.wrap(keccak256(abi.encodePacked(targetSchainName)));
        communityLocker.checkAllowedToSendMessage(targetSchainHash, msg.sender);
        _exitBatch(targetSchainHash, tokenManagers[targetSchainHash], contractOnMainnet, msg.sender, ids, amounts);
    }

    /**
     * @dev Allows MessageProxy to post operational message from mainnet
     * or SKALE chains.
     *
     * Requirements:
     *
     * - MessageProxy must be the sender.
     * - `fromChainHash` must exist in TokenManagerERC1155 addresses.
     */
    function postMessage(
        SchainHash fromChainHash,
        address sender,
        bytes calldata data
    )
        external
        override
        onlyMessageProxy
        checkReceiverChain(fromChainHash, sender)
    {
        Messages.MessageType operation = Messages.getMessageType(data);
        address receiver = address(0);
        if (
            operation == Messages.MessageType.TRANSFER_ERC1155 ||
            operation == Messages.MessageType.TRANSFER_ERC1155_AND_TOKEN_INFO
        ) {
            receiver = _sendERC1155(fromChainHash, data);
        } else if (
            operation == Messages.MessageType.TRANSFER_ERC1155_BATCH ||
            operation == Messages.MessageType.TRANSFER_ERC1155_BATCH_AND_TOKEN_INFO
        ) {
            receiver = _sendERC1155Batch(fromChainHash, data);
        } else {
            revert("MessageType is unknown");
        }
    }

    /**
     * @dev Allows Schain owner to register an ERC1155 token clone in the token manager.
     */
    function addERC1155TokenByOwner(
        string calldata originChainName,
        address erc1155OnOriginChain,
        address newErc1155OnSchain
    )
        external
        override
        onlyTokenRegistrar
    {
        SchainHash originChainHash = SchainHash.wrap(keccak256(abi.encodePacked(originChainName)));
        require(messageProxy.isConnectedChain(originChainName), "Chain is not connected");
        require(newErc1155OnSchain.isContract(), "Given address is not a contract");
        require(address(clonesErc1155[originChainHash][erc1155OnOriginChain]) == address(0), "Could not relink clone");
        require(!addedClones[ERC1155OnChain(newErc1155OnSchain)], "Clone was already added");
        clonesErc1155[originChainHash][erc1155OnOriginChain] = ERC1155OnChain(newErc1155OnSchain);
        addedClones[ERC1155OnChain(newErc1155OnSchain)] = true;
        emit ERC1155TokenAdded(originChainHash, erc1155OnOriginChain, newErc1155OnSchain);
    }

    /**
     * @dev Is called once during contract deployment.
     */
    function initialize(
        string memory newChainName,
        IMessageProxyForSchain newMessageProxy,
        ITokenManagerLinker newIMALinker,
        ICommunityLocker newCommunityLocker,
        address newDepositBox
    )
        external
        override
        initializer
    {
        TokenManager.initializeTokenManager(
            newChainName,
            newMessageProxy,
            newIMALinker,
            newCommunityLocker,
            newDepositBox
        );
    }

    function onERC1155Received(
        address operator,
        address,
        uint256,
        uint256,
        bytes calldata
    )
        external
        view
        override
        returns(bytes4)
    {
        require(operator == address(this), "Revert ERC1155 transfer");
        return bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"));
    }

    function onERC1155BatchReceived(
        address operator,
        address,
        uint256[] calldata,
        uint256[] calldata,
        bytes calldata
    )
        external
        view
        override
        returns(bytes4)
    {
        require(operator == address(this), "Revert ERC1155 batch transfer");
        return bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"));
    }

    /**
     * @dev Checks whether contract supports such interface (first 4 bytes of method name and its params).
     */
    function supportsInterface(
        bytes4 interfaceId
    )
        public
        view
        override(AccessControlEnumerableUpgradeable, ERC1155ReceiverUpgradeableWithoutGap)
        returns (bool)
    {
        return interfaceId == type(TokenManager).interfaceId
            || super.supportsInterface(interfaceId);
    }


    /**
     * @dev Allows TokenManager to send ERC1155 tokens.
     *
     * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.
     * Emits a {ERC20TokenReceived} event on success.
     */
    function _sendERC1155(SchainHash fromChainHash, bytes calldata data) private returns (address) {
        Messages.MessageType messageType = Messages.getMessageType(data);
        address receiver;
        address token;
        uint256 id;
        uint256 amount;
        ERC1155OnChain contractOnSchain;
        if (messageType == Messages.MessageType.TRANSFER_ERC1155){
            Messages.TransferErc1155Message memory message = Messages.decodeTransferErc1155Message(data);
            receiver = message.receiver;
            token = message.token;
            id = message.id;
            amount = message.amount;
            contractOnSchain = clonesErc1155[fromChainHash][token];
        } else {
            Messages.TransferErc1155AndTokenInfoMessage memory message =
                Messages.decodeTransferErc1155AndTokenInfoMessage(data);
            receiver = message.baseErc1155transfer.receiver;
            token = message.baseErc1155transfer.token;
            id = message.baseErc1155transfer.id;
            amount = message.baseErc1155transfer.amount;
            contractOnSchain = clonesErc1155[fromChainHash][token];
            if (address(contractOnSchain) == address(0)) {
                require(automaticDeploy, "Automatic deploy is disabled");
                contractOnSchain = new ERC1155OnChain(message.tokenInfo.uri);
                clonesErc1155[fromChainHash][token] = contractOnSchain;
                addedClones[contractOnSchain] = true;
                emit ERC1155TokenCreated(fromChainHash, token, address(contractOnSchain));
            }
        }
        if (
            messageType == Messages.MessageType.TRANSFER_ERC1155 &&
            fromChainHash != MAINNET_HASH &&
            _schainToERC1155[fromChainHash].contains(token)
        ) {
            require(token.isContract(), "Incorrect main chain token");
            _removeTransferredAmount(fromChainHash, token, _asSingletonArray(id), _asSingletonArray(amount));
            IERC1155Upgradeable(token).safeTransferFrom(address(this), receiver, id, amount, "");
        } else {
            contractOnSchain.mint(receiver, id, amount, "");
        }
        emit ERC1155TokenReceived(
            fromChainHash,
            token,
            address(contractOnSchain),
            _asSingletonArray(id),
            _asSingletonArray(amount)
        );
        messageProxy.topUpReceiverBalance(payable(receiver));
        return receiver;
    }

    /**
     * @dev Allows TokenManager to send a batch of ERC1155 tokens.
     *
     * Emits a {ERC20TokenCreated} event if token did not exist and was automatically deployed.
     * Emits a {ERC20TokenReceived} event on success.
     */
    function _sendERC1155Batch(SchainHash fromChainHash, bytes calldata data) private returns (address) {
        Messages.MessageType messageType = Messages.getMessageType(data);
        address receiver;
        address token;
        uint256[] memory ids;
        uint256[] memory amounts;
        ERC1155OnChain contractOnSchain;
        if (messageType == Messages.MessageType.TRANSFER_ERC1155_BATCH){
            Messages.TransferErc1155BatchMessage memory message = Messages.decodeTransferErc1155BatchMessage(data);
            receiver = message.receiver;
            token = message.token;
            ids = message.ids;
            amounts = message.amounts;
            contractOnSchain = clonesErc1155[fromChainHash][token];
        } else {
            Messages.TransferErc1155BatchAndTokenInfoMessage memory message =
                Messages.decodeTransferErc1155BatchAndTokenInfoMessage(data);
            receiver = message.baseErc1155Batchtransfer.receiver;
            token = message.baseErc1155Batchtransfer.token;
            ids = message.baseErc1155Batchtransfer.ids;
            amounts = message.baseErc1155Batchtransfer.amounts;
            contractOnSchain = clonesErc1155[fromChainHash][token];
            if (address(contractOnSchain) == address(0)) {
                require(automaticDeploy, "Automatic deploy is disabled");
                contractOnSchain = new ERC1155OnChain(message.tokenInfo.uri);
                clonesErc1155[fromChainHash][token] = contractOnSchain;
                emit ERC1155TokenCreated(fromChainHash, token, address(contractOnSchain));
            }
        }
        if (
            messageType == Messages.MessageType.TRANSFER_ERC1155_BATCH &&
            fromChainHash != MAINNET_HASH &&
            _schainToERC1155[fromChainHash].contains(token)
        ) {
            require(token.isContract(), "Incorrect main chain token");
            _removeTransferredAmount(fromChainHash, token, ids, amounts);
            IERC1155Upgradeable(token).safeBatchTransferFrom(address(this), receiver, ids, amounts, "");
        } else {
            contractOnSchain.mintBatch(receiver, ids, amounts, "");
        }
        emit ERC1155TokenReceived(fromChainHash, token, address(contractOnSchain), ids, amounts);
        messageProxy.topUpReceiverBalance(payable(receiver));
        return receiver;
    }

    /**
     * @dev Burn tokens on schain and send message to unlock them on target chain.
     */
    function _exit(
        SchainHash chainHash,
        address messageReceiver,
        address contractOnMainChain,
        address to,
        uint256 id,
        uint256 amount
    )
        private
    {
        bool isMainChainToken;
        ERC1155OnChain contractOnSchain = clonesErc1155[chainHash][contractOnMainChain];
        if (address(contractOnSchain) == address(0)) {
            contractOnSchain = ERC1155OnChain(contractOnMainChain);
            require(!addedClones[contractOnSchain], "Incorrect main chain token");
            isMainChainToken = true;
        }
        require(address(contractOnSchain).isContract(), "No token clone on schain");
        require(contractOnSchain.isApprovedForAll(msg.sender, address(this)), "Not allowed ERC1155 Token");
        bytes memory data = Messages.encodeTransferErc1155Message(contractOnMainChain, to, id, amount);
        if (isMainChainToken) {
            require(chainHash != MAINNET_HASH, "Main chain token could not be transfered to Mainnet");
            data = _receiveERC1155(
                chainHash,
                address(contractOnSchain),
                msg.sender,
                id,
                amount
            );
            _saveTransferredAmount(
                chainHash,
                address(contractOnSchain),
                _asSingletonArray(id),
                _asSingletonArray(amount)
            );
            contractOnSchain.safeTransferFrom(msg.sender, address(this), id, amount, "");
        } else {
            contractOnSchain.burn(msg.sender, id, amount);
        }
        messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);
    }

    /**
     * @dev Burn batch of tokens on schain and send message to unlock them on target chain.
     */
    function _exitBatch(
        SchainHash chainHash,
        address messageReceiver,
        address contractOnMainChain,
        address to,
        uint256[] calldata ids,
        uint256[] calldata amounts
    )
        private
    {
        bool isMainChainToken;
        ERC1155OnChain contractOnSchain = clonesErc1155[chainHash][contractOnMainChain];
        if (address(contractOnSchain) == address(0)) {
            contractOnSchain = ERC1155OnChain(contractOnMainChain);
            require(!addedClones[contractOnSchain], "Incorrect main chain token");
            isMainChainToken = true;
        }
        require(address(contractOnSchain).isContract(), "No token clone on schain");
        require(contractOnSchain.isApprovedForAll(msg.sender, address(this)), "Not allowed ERC1155 Token");
        bytes memory data = Messages.encodeTransferErc1155BatchMessage(contractOnMainChain, to, ids, amounts);
        if (isMainChainToken) {
            require(chainHash != MAINNET_HASH, "Main chain token could not be transfered to Mainnet");
            data = _receiveERC1155Batch(
                chainHash,
                address(contractOnSchain),
                msg.sender,
                ids,
                amounts
            );
            _saveTransferredAmount(chainHash, address(contractOnSchain), ids, amounts);
            contractOnSchain.safeBatchTransferFrom(msg.sender, address(this), ids, amounts, "");
        } else {
            contractOnSchain.burnBatch(msg.sender, ids, amounts);
        }
        messageProxy.postOutgoingMessage(chainHash, messageReceiver, data);
    }

    /**
     * @dev Saves amount of tokens that was transferred to schain.
     */
    function _saveTransferredAmount(
        SchainHash chainHash,
        address erc1155Token,
        uint256[] memory ids,
        uint256[] memory amounts
    ) private {
        require(ids.length == amounts.length, "Incorrect length of arrays");
        for (uint256 i = 0; i < ids.length; i++)
            transferredAmount[chainHash][erc1155Token][ids[i]] += amounts[i];
    }

    /**
     * @dev Removes amount of tokens that was transferred from schain.
     */
    function _removeTransferredAmount(
        SchainHash chainHash,
        address erc1155Token,
        uint256[] memory ids,
        uint256[] memory amounts
    ) private {
        require(ids.length == amounts.length, "Incorrect length of arrays");
        for (uint256 i = 0; i < ids.length; i++)
            transferredAmount[chainHash][erc1155Token][ids[i]] -= amounts[i];
    }

    /**
     * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.
     *
     * Emits an {ERC1155TokenReady} event.
     *
     * Requirements:
     *
     * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.
     */
    function _receiveERC1155(
        SchainHash chainHash,
        address erc1155OnMainChain,
        address to,
        uint256 id,
        uint256 amount
    )
        private
        returns (bytes memory data)
    {
        bool isERC1155AddedToSchain = _schainToERC1155[chainHash].contains(erc1155OnMainChain);
        if (!isERC1155AddedToSchain) {
            _addERC1155ForSchain(chainHash, erc1155OnMainChain);
            data = Messages.encodeTransferErc1155AndTokenInfoMessage(
                erc1155OnMainChain,
                to,
                id,
                amount,
                _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainChain))
            );
        } else {
            data = Messages.encodeTransferErc1155Message(erc1155OnMainChain, to, id, amount);
        }

        emit ERC1155TokenReady(chainHash, erc1155OnMainChain, _asSingletonArray(id), _asSingletonArray(amount));
    }

    /**
     * @dev Allows DepositBoxERC1155 to receive ERC1155 tokens.
     *
     * Emits an {ERC1155TokenReady} event.
     *
     * Requirements:
     *
     * - Whitelist should be turned off for auto adding tokens to DepositBoxERC1155.
     */
    function _receiveERC1155Batch(
        SchainHash chainHash,
        address erc1155OnMainChain,
        address to,
        uint256[] calldata ids,
        uint256[] calldata amounts
    )
        private
        returns (bytes memory data)
    {
        bool isERC1155AddedToSchain = _schainToERC1155[chainHash].contains(erc1155OnMainChain);
        if (!isERC1155AddedToSchain) {
            _addERC1155ForSchain(chainHash, erc1155OnMainChain);
            data = Messages.encodeTransferErc1155BatchAndTokenInfoMessage(
                erc1155OnMainChain,
                to,
                ids,
                amounts,
                _getTokenInfo(IERC1155MetadataURIUpgradeable(erc1155OnMainChain))
            );
        } else {
            data = Messages.encodeTransferErc1155BatchMessage(erc1155OnMainChain, to, ids, amounts);
        }
        emit ERC1155TokenReady(chainHash, erc1155OnMainChain, ids, amounts);
    }

    /**
     * @dev Adds an ERC1155 token to DepositBoxERC1155.
     *
     * Emits an {ERC1155TokenAdded} event.
     *
     * Requirements:
     *
     * - Given address should be contract.
     */
    function _addERC1155ForSchain(SchainHash chainHash, address erc1155OnMainChain) private {
        require(erc1155OnMainChain.isContract(), "Given address is not a contract");
        require(!_schainToERC1155[chainHash].contains(erc1155OnMainChain), "ERC1155 Token was already added");
        _schainToERC1155[chainHash].add(erc1155OnMainChain);
        emit ERC1155TokenAdded(chainHash, erc1155OnMainChain, address(0));
    }

    /**
     * @dev Returns info about ERC1155 token.
     */
    function _getTokenInfo(
        IERC1155MetadataURIUpgradeable erc1155
    )
        private
        view
        returns (Messages.Erc1155TokenInfo memory)
    {
        return Messages.Erc1155TokenInfo({uri: erc1155.uri(0)});
    }

    /**
     * @dev Create array with single element in it.
     */
    function _asSingletonArray(uint256 element) private pure returns (uint256[] memory array) {
        array = new uint256[](1);
        array[0] = element;
    }

}

exec
/bin/bash -lc "sed -n '1,220p' contracts/extensions/ERC721ReferenceMintAndMetadataMainnet.sol" in /tmp/codex-sryvig8b
 succeeded in 0ms:
// SPDX-License-Identifier: AGPL-3.0-only

/**
 *   ERC721ReferenceMintAndMetadataMainnet.sol - SKALE Interchain Messaging Agent
 *   Copyright (C) 2021-Present SKALE Labs
 *   @author Artem Payvin
 *
 *   SKALE IMA is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published
 *   by the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   SKALE IMA is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with SKALE IMA.  If not, see <https://www.gnu.org/licenses/>.
 */

pragma solidity 0.8.27;

import "@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataMainnet.sol";

import "../schain/tokens/ERC721OnChain.sol";
import "./interfaces/MessageReceiver.sol";


// This contract runs on the main net and accepts deposits
contract ERC721ReferenceMintAndMetadataMainnet is MessageReceiver, IERC721ReferenceMintAndMetadataMainnet {

    address public immutable erc721ContractOnMainnet;
    address public senderContractOnSchain;
    string public schainName;

    address public immutable owner;

    modifier onlyOwner() {
        require(msg.sender == owner, "Sender is not an owner");
        _;
    }

    constructor(
        address newMessageProxyAddress,
        address newErc721Contract,
        string memory newSchainName
    )
        MessageProxyClient(newMessageProxyAddress)
    {
        require(newErc721Contract != address(0), "ERC721 contract has to be set");
        erc721ContractOnMainnet = newErc721Contract;
        schainName = newSchainName;
        owner = msg.sender;
    }

    function setSenderContractOnSchain(address newSenderContractOnSchain) external override onlyOwner {
        require(newSenderContractOnSchain != address(0), "Sender contract has to be set");
        senderContractOnSchain = newSenderContractOnSchain;
    }

    function postMessage(
        SchainHash schainHash,
        address sender,
        bytes calldata data
    )
        external
        override
        onlyMessageProxy
    {
        require(schainHash == SchainHash.wrap(keccak256(abi.encodePacked(schainName))), "Incorrect name of schain");
        require(sender == senderContractOnSchain, "Incorrect sender contract");
        address to;
        uint256 tokenId;
        string memory tokenURI;
        (to, tokenId, tokenURI) = abi.decode(data, (address, uint256, string));
        ERC721OnChain(erc721ContractOnMainnet).mint(address(this), tokenId);
        require(
            ERC721OnChain(erc721ContractOnMainnet).setTokenURI(tokenId, tokenURI),
            "Token URI was not set"
        );
        ERC721OnChain(erc721ContractOnMainnet).transferFrom(address(this), to, tokenId);
    }
}

exec
/bin/bash -lc "sed -n '1,180p' contracts/extensions/ERC721ReferenceMintAndMetadataSchain.sol" in /tmp/codex-sryvig8b
 succeeded in 0ms:
// SPDX-License-Identifier: AGPL-3.0-only

/**
 *   ERC721ReferenceMintAndMetadataSchain.sol - SKALE Interchain Messaging Agent
 *   Copyright (C) 2019-Present SKALE Labs
 *   @author Artem Payvin
 *
 *   SKALE IMA is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published
 *   by the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   SKALE IMA is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with SKALE IMA.  If not, see <https://www.gnu.org/licenses/>.
 */

pragma solidity 0.8.27;

import "@skalenetwork/ima-interfaces/extensions/IERC721ReferenceMintAndMetadataSchain.sol";

import "../schain/tokens/ERC721OnChain.sol";
import "./interfaces/MessageSender.sol";


/**
 * @title Token Manager
 * @dev Runs on SKALE Chains, accepts messages from mainnet, and instructs
 * TokenFactory to create clones.
  When a user exits a SKALE chain, TokenFactory
 * burns tokens.
 */
contract ERC721ReferenceMintAndMetadataSchain is MessageSender, IERC721ReferenceMintAndMetadataSchain {

    address public immutable erc721ContractOnSchain;
    address public immutable receiverContractOnMainnet;

    constructor(
        address newMessageProxyAddress,
        address newErc721ContractOnSchain,
        address newReceiverContractOnMainnet
    )
        MessageProxyClient(newMessageProxyAddress)
    {
        require(newErc721ContractOnSchain != address(0), "ERC721 contract has to be set");
        require(newReceiverContractOnMainnet != address(0), "Receiver contract has to be set");
        erc721ContractOnSchain = newErc721ContractOnSchain;
        receiverContractOnMainnet = newReceiverContractOnMainnet;
    }

    function sendTokenToMainnet(address receiver, uint256 tokenId) external override {
        require(
            ERC721OnChain(erc721ContractOnSchain).getApproved(tokenId) == address(this),
            "Not allowed ERC721 Token"
        );
        ERC721OnChain(erc721ContractOnSchain).transferFrom(msg.sender, address(this), tokenId);
        string memory tokenURI = ERC721OnChain(erc721ContractOnSchain).tokenURI(tokenId);
        ERC721OnChain(erc721ContractOnSchain).burn(tokenId);
        bytes memory data = encodeParams(receiver, tokenId, tokenURI);
        _sendMessage("Mainnet", receiverContractOnMainnet, data);
    }

    function encodeParams(
        address receiver,
        uint256 tokenId,
        string memory tokenURI
    )
        public
        pure
        override
        returns (bytes memory data)
    {
        data = abi.encode(receiver, tokenId, tokenURI);
    }
}

exec
/bin/bash -lc "sed -n '1,140p' contracts/extensions/interfaces/MessageProxyClient.sol && printf '\\n=====\\n' && sed -n '1,120p' contracts/extensions/interfaces/MessageReceiver.sol && printf '\\n=====\\n' && sed -n '1,120p' contracts/extensions/interfaces/MessageSender.sol" in /tmp/codex-sryvig8b
 succeeded in 0ms:
// SPDX-License-Identifier: AGPL-3.0-only

/**
 *   MessageProxyClient.sol - SKALE Interchain Messaging Agent
 *   Copyright (C) 2021-Present SKALE Labs
 *   @author Artem Payvin
 *
 *   SKALE IMA is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published
 *   by the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   SKALE IMA is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with SKALE IMA.  If not, see <https://www.gnu.org/licenses/>.
 */

pragma solidity 0.8.27;

import "../../MessageProxy.sol";

abstract contract MessageProxyClient {
    MessageProxy public immutable messageProxy;

    modifier onlyMessageProxy() {
        require(msg.sender == address(messageProxy), "Sender is not a message proxy");
        _;
    }

    constructor(address newMessageProxyAddress) {
        messageProxy = MessageProxy(newMessageProxyAddress);
    }
}

=====
// SPDX-License-Identifier: AGPL-3.0-only

/**
 *   MessageReceiver.sol - SKALE Interchain Messaging Agent
 *   Copyright (C) 2021-Present SKALE Labs
 *   @author Artem Payvin
 *
 *   SKALE IMA is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published
 *   by the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   SKALE IMA is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with SKALE IMA.  If not, see <https://www.gnu.org/licenses/>.
 */

pragma solidity 0.8.27;

import "@skalenetwork/ima-interfaces/IMessageReceiver.sol";

import "./MessageProxyClient.sol";


// solhint-disable-next-line no-empty-blocks
abstract contract MessageReceiver is MessageProxyClient, IMessageReceiver {}

=====
// SPDX-License-Identifier: AGPL-3.0-only

/**
 *   MessageSender.sol - SKALE Interchain Messaging Agent
 *   Copyright (C) 2021-Present SKALE Labs
 *   @author Artem Payvin
 *
 *   SKALE IMA is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published
 *   by the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   SKALE IMA is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with SKALE IMA.  If not, see <https://www.gnu.org/licenses/>.
 */

pragma solidity 0.8.27;

import "./MessageProxyClient.sol";

abstract contract MessageSender is MessageProxyClient {

    function _sendMessage(
        string memory targetChainName,
        address targetContract,
        bytes memory data
    ) internal {
        messageProxy.postOutgoingMessage(
            SchainHash.wrap(keccak256(abi.encodePacked(targetChainName))),
            targetContract,
            data
        );
    }
}

exec
/bin/bash -lc "sed -n '1,180p' contracts/schain/tokens/ERC20OnChain.sol && printf '\\n=====\\n' && sed -n '1,220p' contracts/schain/tokens/ERC721OnChain.sol && printf '\\n=====\\n' && sed -n '1,180p' contracts/schain/tokens/ERC1155OnChain.sol && printf '\\n=====\\n' && sed -n '1,180p' contracts/schain/tokens/EthErc20.sol" in /tmp/codex-sryvig8b
 succeeded in 0ms:
// SPDX-License-Identifier: AGPL-3.0-only

/**
 *   ERC20OnChain.sol - SKALE Interchain Messaging Agent
 *   Copyright (C) 2021-Present SKALE Labs
 *   @author Artem Payvin
 *   @author Dmytro Stebaiev
 *
 *   SKALE IMA is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published
 *   by the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   SKALE IMA is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with SKALE IMA.  If not, see <https://www.gnu.org/licenses/>.
 */

pragma solidity 0.8.27;

import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol";
import "@skalenetwork/ima-interfaces/schain/tokens/IERC20OnChain.sol";


/**
 * @title ERC20OnChain
 * @dev ERC20 token that is used as an automatically deployed clone of ERC20 on mainnet.
 */
contract ERC20OnChain is AccessControlEnumerableUpgradeable, ERC20BurnableUpgradeable, IERC20OnChain {

    /**
     * @dev id of a role that allows token minting.
     */
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");

    constructor(
        string memory contractName,
        string memory contractSymbol
    ) initializer
    {
        AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();
        ERC20Upgradeable.__ERC20_init(contractName, contractSymbol);
        ERC20BurnableUpgradeable.__ERC20Burnable_init();
        _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);
        _setupRole(MINTER_ROLE, _msgSender());
    }

    /**
     * @dev Mint tokens.
     *
     * Requirements:
     *
     * - sender must be granted with {MINTER_ROLE}.
     */
    function mint(address account, uint256 value) external override {
        require(hasRole(MINTER_ROLE, _msgSender()), "Sender is not a Minter");
        _mint(account, value);
    }
}

=====
// SPDX-License-Identifier: AGPL-3.0-only

/**
 *   ERC721OnChain.sol - SKALE Interchain Messaging Agent
 *   Copyright (C) 2021-Present SKALE Labs
 *   @author Artem Payvin
 *   @author Dmytro Stebaiev
 *
 *   SKALE IMA is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published
 *   by the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   SKALE IMA is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with SKALE IMA.  If not, see <https://www.gnu.org/licenses/>.
 */

pragma solidity 0.8.27;

import "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol";
import "@skalenetwork/ima-interfaces/schain/tokens/IERC721OnChain.sol";


/**
 * @title ERC721OnChain
 * @dev ERC721 token that is used as an automatically deployed clone of ERC721 on mainnet.
 */
contract ERC721OnChain is
    AccessControlEnumerableUpgradeable,
    ERC721BurnableUpgradeable,
    ERC721URIStorageUpgradeable,
    IERC721OnChain
{

    /**
     * @dev id of a role that allows token minting.
     */
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");

    constructor(
        string memory contractName,
        string memory contractSymbol
    ) initializer
    {
        AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();
        ERC721Upgradeable.__ERC721_init(contractName, contractSymbol);
        ERC721BurnableUpgradeable.__ERC721Burnable_init();
        _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);
        _setupRole(MINTER_ROLE, _msgSender());
    }

    /**
     * @dev Set URI of ERC721 token.
     *
     * Requirements:
     *
     * - token with {tokenId} must exist.
     * - sender must be the token owner or approved for the token.
     */
    function setTokenURI(uint256 tokenId, string calldata tokenUri)
        external
        override
        returns (bool)
    {
        require(_exists(tokenId), "Token does not exists");
        require(
            _isApprovedOrOwner(msg.sender, tokenId) ||
            hasRole(MINTER_ROLE, _msgSender()),
            "Sender can not set token URI"
        );
        _setTokenURI(tokenId, tokenUri);
        return true;
    }

    /**
     * @dev Mint token.
     *
     * Requirements:
     *
     * - sender must be granted with {MINTER_ROLE}.
     */
    function mint(address account, uint256 tokenId)
        external
        override
    {
        require(hasRole(MINTER_ROLE, _msgSender()), "Sender is not a Minter");
        _mint(account, tokenId);
    }

    /**
     * @dev Check if contract support {interfaceId} interface.
     *
     * See https://eips.ethereum.org/EIPS/eip-165 for more details.
     */
    function supportsInterface(
        bytes4 interfaceId
    )
        public
        view
        override(AccessControlEnumerableUpgradeable, ERC721Upgradeable, ERC721URIStorageUpgradeable)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }

    /**
     * @dev Get token URI.
     */
    function tokenURI(
        uint256 tokenId
    )
        public
        view
        override (ERC721Upgradeable, ERC721URIStorageUpgradeable)
        returns (string memory)
    {
        return ERC721URIStorageUpgradeable.tokenURI(tokenId);
    }

    // private

    /**
     * @dev Burn {tokenId}.
     */
    function _burn(uint256 tokenId) internal override (ERC721Upgradeable, ERC721URIStorageUpgradeable) {
        ERC721URIStorageUpgradeable._burn(tokenId);
    }
}

=====
// SPDX-License-Identifier: AGPL-3.0-only

/**
 *   ERC1155OnChain.sol - SKALE Interchain Messaging Agent
 *   Copyright (C) 2021-Present SKALE Labs
 *   @author Artem Payvin
 *   @author Dmytro Stebaiev
 *
 *   SKALE IMA is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published
 *   by the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   SKALE IMA is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with SKALE IMA.  If not, see <https://www.gnu.org/licenses/>.
 */

pragma solidity 0.8.27;

import "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol";
import "@skalenetwork/ima-interfaces/schain/tokens/IERC1155OnChain.sol";


/**
 * @title ERC1155OnChain
 * @dev ERC1155 token that is used as an automatically deployed clone of ERC1155 on mainnet.
 */
contract ERC1155OnChain is AccessControlEnumerableUpgradeable, ERC1155BurnableUpgradeable, IERC1155OnChain {

    /**
     * @dev id of a role that allows token minting.
     */
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");

    constructor(
        string memory uri
    ) initializer
    {
        AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();
        ERC1155Upgradeable.__ERC1155_init(uri);
        ERC1155BurnableUpgradeable.__ERC1155Burnable_init();

        _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);
        _setupRole(MINTER_ROLE, _msgSender());
    }

    /**
     * @dev Mint tokens.
     *
     * Requirements:
     *
     * - sender must be granted with {MINTER_ROLE}.
     */
    function mint(
        address account,
        uint256 id,
        uint256 amount,
        bytes memory data
    )
        external
        override
    {
        require(hasRole(MINTER_ROLE, _msgSender()), "Sender is not a Minter");
        _mint(account, id, amount, data);
    }

    /**
     * @dev Mint batch of tokens.
     *
     * Requirements:
     *
     * - sender must be granted with {MINTER_ROLE}.
     */
    function mintBatch(
        address account,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    )
        external
        override
    {
        require(hasRole(MINTER_ROLE, _msgSender()), "Sender is not a Minter");
        _mintBatch(account, ids, amounts, data);
    }

    /**
     * @dev Check if contract support {interfaceId} interface.
     *
     * See https://eips.ethereum.org/EIPS/eip-165 for more details.
     */
    function supportsInterface(
        bytes4 interfaceId
    )
        public
        view
        override(AccessControlEnumerableUpgradeable, ERC1155Upgradeable)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }
}

=====
// SPDX-License-Identifier: AGPL-3.0-only

/**
 *   EthErc20.sol - SKALE Interchain Messaging Agent
 *   Copyright (C) 2019-Present SKALE Labs
 *   @author Artem Payvin
 *
 *   SKALE IMA is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published
 *   by the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   SKALE IMA is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with SKALE IMA.  If not, see <https://www.gnu.org/licenses/>.
 */

pragma solidity 0.8.27;

import "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol";
import "@skalenetwork/ima-interfaces/schain/tokens/IEthErc20.sol";


/**
 * @title EthErc20
 * @dev ERC20 token that represents ETH on mainnet.
 */
contract EthErc20 is AccessControlEnumerableUpgradeable, ERC20BurnableUpgradeable, IEthErc20 {

    /**
     * @dev id of a role that allows token minting.
     */
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");

    /**
     * @dev id of a role that allows token burning.
     */
    bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE");

    /**
     * @dev Mint tokens.
     *
     * Requirements:
     *
     * - sender must be granted with {MINTER_ROLE}.
     */
    function mint(address account, uint256 amount) external override {
        require(hasRole(MINTER_ROLE, _msgSender()), "MINTER role is required");
        _mint(account, amount);
    }

    /**
     * @dev Burn tokens for any account.
     *
     * Requirements:
     *
     * - sender must be granted with {BURNER_ROLE}.
     */
    function forceBurn(address account, uint256 amount) external override {
        require(hasRole(BURNER_ROLE, _msgSender()), "BURNER role is required");
        _burn(account, amount);
    }

    /**
     * @dev Is called once during contract deployment.
     */
    function initialize(address tokenManagerEthAddress)
        external
        override
        initializer
    {
        AccessControlEnumerableUpgradeable.__AccessControlEnumerable_init();
        ERC20Upgradeable.__ERC20_init("ERC20 Ether Clone", "ETHC");
        ERC20BurnableUpgradeable.__ERC20Burnable_init();
        _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
        _setupRole(MINTER_ROLE, tokenManagerEthAddress);
        _setupRole(BURNER_ROLE, tokenManagerEthAddress);
    }
}

exec
/bin/bash -lc "sed -n '1,220p' contracts/test/SkaleVerifierMock.sol && printf '\\n=====\\n' && sed -n '1,140p' contracts/test/MessageProxyForSchainWithoutSignature.sol" in /tmp/codex-sryvig8b
 succeeded in 0ms:
// SPDX-License-Identifier: AGPL-3.0-only

/**
 *   TestSkaleVerifier.sol - SKALE Interchain Messaging Agent
 *   Copyright (C) 2021-Present SKALE Labs
 *   @author Artem Payvin
 *
 *   SKALE IMA is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published
 *   by the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   SKALE IMA is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with SKALE IMA.  If not, see <https://www.gnu.org/licenses/>.
 */


pragma solidity 0.8.27;

import "../schain/bls/FieldOperations.sol";

import "./PrecompiledMock.sol";


interface ISkaleVerifierMock {
    function verify(
        IFieldOperations.Fp2Point calldata signature,
        bytes32 hash,
        uint counter,
        uint hashA,
        uint hashB,
        IFieldOperations.G2Point calldata publicKey
    )
        external
        view
        returns (bool);
}


contract SkaleVerifierMock is ISkaleVerifierMock {

    /**
    * @dev Verifies a BLS signature.
    *
    * Requirements:
    *
    * - Signature is in G1.
    * - Hash is in G1.
    * - G2.one in G2.
    * - Public Key in G2.
    */
    function verify(
        IFieldOperations.Fp2Point calldata signature,
        bytes32 hash,
        uint counter,
        uint hashA,
        uint hashB,
        IFieldOperations.G2Point calldata publicKey
    )
        external
        view
        override
        returns (bool)
    {
        require(G1Operations.checkRange(signature), "Signature is not valid");
        if (!_checkHashToGroupWithHelper(
            hash,
            counter,
            hashA,
            hashB
            )
        )
        {
            return false;
        }

        uint newSignB = G1Operations.negate(signature.b);
        require(G1Operations.isG1Point(signature.a, newSignB) || true, "Sign not in G1");
        require(G1Operations.isG1Point(hashA, hashB) || true, "Hash not in G1");

        IFieldOperations.G2Point memory g2 = G2Operations.getG2Generator();
        require(
            G2Operations.isG2(publicKey),
            "Public Key not in G2"
        );

        return PrecompiledMock.bn256Pairing(
            signature.a, newSignB,
            g2.x.b, g2.x.a, g2.y.b, g2.y.a,
            hashA, hashB,
            publicKey.x.b, publicKey.x.a, publicKey.y.b, publicKey.y.a
        );
        // return true;
    }

    function _checkHashToGroupWithHelper(
        bytes32 hash,
        uint counter,
        uint hashA,
        uint hashB
    )
        private
        pure
        returns (bool)
    {
        if (counter > 100) {
            return false;
        }
        uint xCoordinate = uint(hash) % Fp2Operations.P;
        xCoordinate = (xCoordinate + counter) % Fp2Operations.P;

        uint ySquared = addmod(
            mulmod(mulmod(xCoordinate, xCoordinate, Fp2Operations.P), xCoordinate, Fp2Operations.P),
            3,
            Fp2Operations.P
        );
        if (hashB < Fp2Operations.P / 2 || mulmod(hashB, hashB, Fp2Operations.P) != ySquared || xCoordinate != hashA) {
            return true;
        }

        return true;
    }
}

=====
// SPDX-License-Identifier: AGPL-3.0-only

/**
 *   MessageProxyForSchainWithoutSignature.sol - SKALE Interchain Messaging Agent
 *   Copyright (C) 2021-Present SKALE Labs
 *   @author Dmytro Stebaiev
 *
 *   SKALE IMA is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published
 *   by the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   SKALE IMA is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with SKALE IMA.  If not, see <https://www.gnu.org/licenses/>.
 */

pragma solidity 0.8.27;

import "./MessageProxyForSchainTester.sol";

contract MessageProxyForSchainWithoutSignature is MessageProxyForSchainTester {

    constructor(string memory schainName)
        MessageProxyForSchainTester(IKeyStorage(address(0)), schainName)
    // solhint-disable-next-line no-empty-blocks
    {}

    function _verifyMessages(
        bytes32,
        Signature calldata
    )
        internal
        pure
        override
        returns (bool)
    {
        return true;
    }
}

exec
/bin/bash -lc "sed -n '1,220p' contracts/schain/bls/SkaleVerifier.sol" in /tmp/codex-sryvig8b
 succeeded in 0ms:
// SPDX-License-Identifier: AGPL-3.0-only

/*
    SkaleVerifier.sol - SKALE Manager
    Copyright (C) 2021-Present SKALE Labs
    @author Dmytro Stebaiev

    SKALE Manager is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published
    by the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    SKALE Manager is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with SKALE Manager.  If not, see <https://www.gnu.org/licenses/>.
*/

pragma solidity 0.8.27;

import "./Precompiled.sol";
import "./FieldOperations.sol";

/**
 * @title SkaleVerifier
 * @dev Contains verify function to perform BLS signature verification.
 */
library SkaleVerifier {
    using Fp2Operations for IFieldOperations.Fp2Point;


    /**
    * @dev Verifies a BLS signature.
    *
    * Requirements:
    *
    * - Signature is in G1.
    * - Hash is in G1.
    * - G2.one in G2.
    * - Public Key in G2.
    */
    function verify(
        IFieldOperations.Fp2Point memory signature,
        bytes32 hash,
        uint counter,
        uint hashA,
        uint hashB,
        IFieldOperations.G2Point memory publicKey
    )
        internal
        view
        returns (bool)
    {
        require(G1Operations.checkRange(signature), "Signature is not valid");
        if (!_checkHashToGroupWithHelper(
            hash,
            counter,
            hashA,
            hashB
            )
        )
        {
            return false;
        }

        uint newSignB = G1Operations.negate(signature.b);
        require(G1Operations.isG1Point(signature.a, newSignB), "Sign not in G1");
        require(G1Operations.isG1Point(hashA, hashB), "Hash not in G1");

        IFieldOperations.G2Point memory g2 = G2Operations.getG2Generator();
        require(
            G2Operations.isG2(publicKey),
            "Public Key not in G2"
        );

        return Precompiled.bn256Pairing(
            signature.a, newSignB,
            g2.x.b, g2.x.a, g2.y.b, g2.y.a,
            hashA, hashB,
            publicKey.x.b, publicKey.x.a, publicKey.y.b, publicKey.y.a
        );
    }

    function _checkHashToGroupWithHelper(
        bytes32 hash,
        uint counter,
        uint hashA,
        uint hashB
    )
        private
        pure
        returns (bool)
    {
        if (counter > 100) {
            return false;
        }
        uint xCoordinate = uint(hash) % Fp2Operations.P;
        xCoordinate = (xCoordinate + counter) % Fp2Operations.P;

        uint ySquared = addmod(
            mulmod(mulmod(xCoordinate, xCoordinate, Fp2Operations.P), xCoordinate, Fp2Operations.P),
            3,
            Fp2Operations.P
        );
        if (hashB < Fp2Operations.P / 2 || mulmod(hashB, hashB, Fp2Operations.P) != ySquared || xCoordinate != hashA) {
            return false;
        }

        return true;
    }
}

exec
/bin/bash -lc "sed -n '1,180p' contracts/schain/bls/Precompiled.sol && printf '\\n=====\\n' && sed -n '1,380p' contracts/schain/bls/FieldOperations.sol" in /tmp/codex-sryvig8b
 succeeded in 0ms:
// SPDX-License-Identifier: AGPL-3.0-only

/*
    Precompiled.sol - SKALE Manager
    Copyright (C) 2021-Present SKALE Labs
    @author Dmytro Stebaiev

    SKALE Manager is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published
    by the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    SKALE Manager is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with SKALE Manager.  If not, see <https://www.gnu.org/licenses/>.
*/

pragma solidity 0.8.27;

/**
 * @title Precompiled
 * @dev This library is a wrapper to call precompiled contracts
 *
 * Defined calls:
 *
 * - bn256Pairing
 */
library Precompiled {

    /**
     * @dev Calls precompiled contract with address 0x8
     * for elliptic curve pairing operations are required in order to perform zkSNARK verification
     * within the block gas limit.
     * see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-197.md for more details
     */
    function bn256Pairing(
        uint x1,
        uint y1,
        uint a1,
        uint b1,
        uint c1,
        uint d1,
        uint x2,
        uint y2,
        uint a2,
        uint b2,
        uint c2,
        uint d2)
        internal view returns (bool)
    {
        bool success;
        uint[12] memory inputToPairing;
        inputToPairing[0] = x1;
        inputToPairing[1] = y1;
        inputToPairing[2] = a1;
        inputToPairing[3] = b1;
        inputToPairing[4] = c1;
        inputToPairing[5] = d1;
        inputToPairing[6] = x2;
        inputToPairing[7] = y2;
        inputToPairing[8] = a2;
        inputToPairing[9] = b2;
        inputToPairing[10] = c2;
        inputToPairing[11] = d2;
        uint[1] memory out;
        // solhint-disable-next-line no-inline-assembly
        assembly {
            success := staticcall(not(0), 8, inputToPairing, mul(12, 0x20), out, 0x20)
        }
        require(success, "Pairing check failed");
        return out[0] != 0;
    }
}

=====
// SPDX-License-Identifier: AGPL-3.0-only

/*
    FieldOperations.sol - SKALE Manager
    Copyright (C) 2021-Present SKALE Labs

    @author Dmytro Stebaiev

    SKALE Manager is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published
    by the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    SKALE Manager is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with SKALE Manager.  If not, see <https://www.gnu.org/licenses/>.
*/

pragma solidity 0.8.27;

import "@skalenetwork/ima-interfaces/schain/bls/IFieldOperations.sol";

import "./Precompiled.sol";


/**
 * @title Fp2Operations
 * @dev This library contains operations of field that is an extension by imaginary unit of
 * a field of division remainders of a prime number
 *
 * Element of field is Fp2Point
 *
 * Prime divisor is P
 *
 * Defined operations:
 *
 * - addition
 * - subtraction
 * - scalar multiplication
 * - multiplication
 * - squaring
 * - comparison for equality
 */
library Fp2Operations {

    /**
     * @dev Prime devisor
     */
    uint constant public P = 21888242871839275222246405745257275088696311157297823662689037894645226208583;

    /**
     * @dev Add {value1} to {value2}
     */
    function addFp2(
        IFieldOperations.Fp2Point memory value1,
        IFieldOperations.Fp2Point memory value2
    )
        internal
        pure
        returns (IFieldOperations.Fp2Point memory)
    {
        return IFieldOperations.Fp2Point({ a: addmod(value1.a, value2.a, P), b: addmod(value1.b, value2.b, P) });
    }

    /**
     * @dev Perform scalar multiplication of {value} by {scalar}
     */
    function scalarMulFp2(
        IFieldOperations.Fp2Point memory value,
        uint scalar
    )
        internal
        pure
        returns (IFieldOperations.Fp2Point memory)
    {
        return IFieldOperations.Fp2Point({ a: mulmod(scalar, value.a, P), b: mulmod(scalar, value.b, P) });
    }

    /**
     * @dev Subtract {subtracted} from {diminished}
     */
    function minusFp2(
        IFieldOperations.Fp2Point memory diminished,
        IFieldOperations.Fp2Point memory subtracted
    )
        internal
        pure
        returns (IFieldOperations.Fp2Point memory difference)
    {
        uint p = P;
        if (diminished.a >= subtracted.a) {
            difference.a = addmod(diminished.a, p - subtracted.a, p);
        } else {
            difference.a = (p - addmod(subtracted.a, p - diminished.a, p)) % p;
        }
        if (diminished.b >= subtracted.b) {
            difference.b = addmod(diminished.b, p - subtracted.b, p);
        } else {
            difference.b = (p - addmod(subtracted.b, p - diminished.b, p)) % p;
        }
    }

    /**
     * @dev Multiply {value1} by {value2}
     */
    function mulFp2(
        IFieldOperations.Fp2Point memory value1,
        IFieldOperations.Fp2Point memory value2
    )
        internal
        pure
        returns (IFieldOperations.Fp2Point memory result)
    {
        uint p = P;
        IFieldOperations.Fp2Point memory point = IFieldOperations.Fp2Point({
            a: mulmod(value1.a, value2.a, p),
            b: mulmod(value1.b, value2.b, p)});
        result.a = addmod(
            point.a,
            mulmod(p - 1, point.b, p),
            p);
        result.b = addmod(
            mulmod(
                addmod(value1.a, value1.b, p),
                addmod(value2.a, value2.b, p),
                p),
            p - addmod(point.a, point.b, p),
            p);
    }

    /**
     * @dev Square {value}
     */
    function squaredFp2(
        IFieldOperations.Fp2Point memory value
    )
        internal
        pure
        returns (IFieldOperations.Fp2Point memory)
    {
        uint p = P;
        uint ab = mulmod(value.a, value.b, p);
        uint multiplication = mulmod(addmod(value.a, value.b, p), addmod(value.a, mulmod(p - 1, value.b, p), p), p);
        return IFieldOperations.Fp2Point({ a: multiplication, b: addmod(ab, ab, p) });
    }

    /**
     * @dev Check if {value1} is equal to {value2}
     */
    function isEqual(
        IFieldOperations.Fp2Point memory value1,
        IFieldOperations.Fp2Point memory value2
    )
        internal
        pure
        returns (bool)
    {
        return value1.a == value2.a && value1.b == value2.b;
    }
}

/**
 * @title G1Operations
 * @dev This library contains operations of a group of elements {x, y}
 * where y^2 = x^3 + 3 mod P and (x + iy) is an element of Fp2
 *
 * Element of the group is Fp2Point
 *
 * Prime divisor is Fp2Operations.P
 *
 * A group generator is {1, 2}
 *
 * Defined operations:
 *
 * - check if a point is in the group G1
 * - check if a point is in the field Fp2
 * - for x of Fp calculate -x
 */
library G1Operations {
    using Fp2Operations for IFieldOperations.Fp2Point;

    /**
     * @dev Get G1 group generator
     */
    function getG1Generator() internal pure returns (IFieldOperations.Fp2Point memory) {
        // Current solidity version does not support Constants of non-value type
        // so we implemented this function
        return IFieldOperations.Fp2Point({
            a: 1,
            b: 2
        });
    }

    /**
     * @dev Check if ({x], {y}) is a G1 element
     */
    function isG1Point(uint x, uint y) internal pure returns (bool) {
        uint p = Fp2Operations.P;
        return mulmod(y, y, p) ==
            addmod(mulmod(mulmod(x, x, p), x, p), 3, p);
    }

    /**
     * @dev Check if {point} is a G1 element
     */
    function isG1(IFieldOperations.Fp2Point memory point) internal pure returns (bool) {
        return isG1Point(point.a, point.b);
    }

    /**
     * @dev Check if {point} is a Fp2 element
     */
    function checkRange(IFieldOperations.Fp2Point memory point) internal pure returns (bool) {
        return point.a < Fp2Operations.P && point.b < Fp2Operations.P;
    }

    /**
     * @dev For {y} of Fp calculate -y
     */
    function negate(uint y) internal pure returns (uint) {
        return (Fp2Operations.P - y) % Fp2Operations.P;
    }

}

/**
 * @title G2Operations
 * @dev This library contains operations of a group of elements {x, y}
 * where y^2 = x^3 + TWISTB and x and y are elements of Fp2
 *
 * Element of the group is G2Point
 *
 * Prime divisor is Fp2Operations.P
 * TWISTB is
 * {
 *     19485874751759354771024239261021720505790618469301721065564631296452457478373,
 *     266929791119991161246907387137283842545076965332900288569378510910307636690
 * }
 * A group generator is
 * {
 *     {
 *         10857046999023057135944570762232829481370756359578518086990519993285655852781,
 *         11559732032986387107991004021392285783925812861821192530917403151452391805634
 *     },
 *     {
 *         8495653923123431417604973247489272438418190587263600148770280649306958101930,
 *         4082367875863433681332203403145435568316851327593401208105741076214120093531
 *     }
 * }
 *
 * Defined operations:
 *
 * - check if a point is in the group G2
 * - check if a point is zero element of group G2
 * - comparison for equality
 */
library G2Operations {
    using Fp2Operations for IFieldOperations.Fp2Point;


    /**
     * @dev Get value of TWISTB
     */
    function getTWISTB() internal pure returns (IFieldOperations.Fp2Point memory) {
        // Current solidity version does not support Constants of non-value type
        // so we implemented this function
        return IFieldOperations.Fp2Point({
            a: 19485874751759354771024239261021720505790618469301721065564631296452457478373,
            b: 266929791119991161246907387137283842545076965332900288569378510910307636690
        });
    }

    /**
     * @dev Get G2 group generator
     */
    function getG2Generator() internal pure returns (IFieldOperations.G2Point memory) {
        // Current solidity version does not support Constants of non-value type
        // so we implemented this function
        return IFieldOperations.G2Point({
            x: IFieldOperations.Fp2Point({
                a: 10857046999023057135944570762232829481370756359578518086990519993285655852781,
                b: 11559732032986387107991004021392285783925812861821192530917403151452391805634
            }),
            y: IFieldOperations.Fp2Point({
                a: 8495653923123431417604973247489272438418190587263600148770280649306958101930,
                b: 4082367875863433681332203403145435568316851327593401208105741076214120093531
            })
        });
    }

    /**
     * @dev Get G2 zero element
     */
    function getG2Zero() internal pure returns (IFieldOperations.G2Point memory) {
        // Current solidity version does not support Constants of non-value type
        // so we implemented this function
        return IFieldOperations.G2Point({
            x: IFieldOperations.Fp2Point({
                a: 0,
                b: 0
            }),
            y: IFieldOperations.Fp2Point({
                a: 1,
                b: 0
            })
        });
    }

    /**
     * @dev Check if ({x}, {y}) is an element of G2
     */
    function isG2Point(
        IFieldOperations.Fp2Point memory x,
        IFieldOperations.Fp2Point memory y
    )
        internal
        pure
        returns (bool)
    {
        if (isG2ZeroPoint(x, y)) {
            return true;
        }
        IFieldOperations.Fp2Point memory squaredY = y.squaredFp2();
        IFieldOperations.Fp2Point memory res = squaredY.minusFp2(
                x.squaredFp2().mulFp2(x)
            ).minusFp2(getTWISTB());
        return res.a == 0 && res.b == 0;
    }

    /**
     * @dev Check if {value} is an element of G2
     */
    function isG2(IFieldOperations.G2Point memory value) internal pure returns (bool) {
        return isG2Point(value.x, value.y);
    }

    /**
     * @dev Check if ({x}, {y}) is a zero element of G2
     */
    function isG2ZeroPoint(
        IFieldOperations.Fp2Point memory x,
        IFieldOperations.Fp2Point memory y
    )
        internal
        pure
        returns (bool)
    {
        return x.a == 0 && x.b == 0 && y.a == 1 && y.b == 0;
    }

    /**
     * @dev Check if {value} is a zero element of G2
     */
    function isG2Zero(IFieldOperations.G2Point memory value) internal pure returns (bool) {
        return value.x.a == 0 && value.x.b == 0 && value.y.a == 1 && value.y.b == 0;
    }

    /**
     * @dev Check if {value1} is equal to {value2}
     */
    function isEqual(
        IFieldOperations.G2Point memory value1,
        IFieldOperations.G2Point memory value2
    )
        internal
        pure
        returns (bool)
    {
        return value1.x.isEqual(value2.x) && value1.y.isEqual(value2.y);
    }
}

exec
/bin/bash -lc "rg -n \"ERC20TransferWithFalseReturn|ERC20TransferWithoutReturn|ERC20IncorrectTransfer|RevertableERC20|fee|burn.*transfer|tax\" contracts/test contracts -g '"'!contracts/test/erc20/ERC20*'"'" in /tmp/codex-sryvig8b
 succeeded in 0ms:
contracts/mainnet/CommunityPool.sol:65:     * @dev Emitted when basefee multiplier was changed
contracts/mainnet/CommunityPool.sol:256:     * @dev Checks whether passed amount is enough to recharge user wallet with current basefee.
contracts/test/erc20/RevertableERC20.sol:4: *   RevertableERC20.sol - SKALE Interchain Messaging Agent
contracts/test/erc20/RevertableERC20.sol:26:interface IRevertableERC20 {
contracts/test/erc20/RevertableERC20.sol:32:contract RevertableERC20 is IRevertableERC20, ERC20Upgradeable {
contracts/test/SafeMock.sol:160:    ///                (e.g. base transaction fee, signature check, payment of the refund)
contracts/test/erc20/RevertableERC20.sol:4: *   RevertableERC20.sol - SKALE Interchain Messaging Agent
contracts/test/erc20/RevertableERC20.sol:26:interface IRevertableERC20 {
contracts/test/erc20/RevertableERC20.sol:32:contract RevertableERC20 is IRevertableERC20, ERC20Upgradeable {
contracts/test/SafeMock.sol:160:    ///                (e.g. base transaction fee, signature check, payment of the refund)
contracts/schain/CommunityLocker.sol:39: * of gas fees for sent messages

exec
/bin/bash -lc "rg -n \"TransferSkipped|retrieveFor\\(|escalate\\(|validateTransfer\\(|rejectTransfer\\(\" contracts/test" in /tmp/codex-sryvig8b
 exited 1 in 0ms:
exec
/bin/bash -lc "nl -ba contracts/mainnet/DepositBoxes/DepositBoxERC20.sol | sed -n '680,715p'
nl -ba contracts/schain/MessageProxyForSchain.sol | sed -n '246,266p'
nl -ba contracts/schain/CommunityLocker.sol | sed -n '252,274p'" in /tmp/codex-sryvig8b
 succeeded in 0ms:
   680	    function depositERC20Direct(
   681	        string calldata schainName,
   682	        address erc20OnMainnet,
   683	        uint256 amount,
   684	        address receiver
   685	    )
   686	        public
   687	        override
   688	        rightTransaction(schainName, receiver)
   689	        whenNotKilled(_schainHash(schainName))
   690	    {
   691	        SchainHash schainHash = _schainHash(schainName);
   692	        address contractReceiver = schainLinks[schainHash];
   693	        require(contractReceiver != address(0), "Unconnected chain");
   694	        require(
   695	            IERC20Upgradeable(erc20OnMainnet).allowance(msg.sender, address(this)) >= amount,
   696	            "DepositBox was not approved for ERC20 token"
   697	        );
   698	        bytes memory data = _receiveERC20(
   699	            schainName,
   700	            erc20OnMainnet,
   701	            receiver,
   702	            amount
   703	        );
   704	        _saveTransferredAmount(schainHash, erc20OnMainnet, amount);
   705	        IERC20MetadataUpgradeable(erc20OnMainnet).safeTransferFrom(msg.sender, address(this), amount);
   706	        messageProxy.postOutgoingMessage(
   707	            schainHash,
   708	            contractReceiver,
   709	            data
   710	        );
   711	    }
   712	
   713	    /**
   714	     * @dev Check if the receiver is in the delay whitelist
   715	     */
   246	    function setMinimumReceiverBalance(uint256 balance) external override onlyConstantSetter {
   247	        emit MinimumReceiverBalanceChanged(minimumReceiverBalance, balance);
   248	        minimumReceiverBalance = balance;
   249	    }
   250	
   251	    /**
   252	     * @dev Sends sFuel to the `receiver` address to satisfy a minimum balance
   253	     */
   254	    function topUpReceiverBalance(address payable receiver) external override {
   255	        require(isContractRegistered(SchainHash.wrap(bytes32(0)), msg.sender), "Sender is not registered");
   256	        uint256 balance = receiver.balance;
   257	        uint256 threshold = minimumReceiverBalance;
   258	        if (balance < threshold) {
   259	            _transferFromEtherbase(receiver, threshold - balance);
   260	        }
   261	    }
   262	
   263	    /**
   264	     * @dev Verify if the message metadata is valid.
   265	     */
   266	    function verifyOutgoingMessageData(
   252	    function setGasPrice(
   253	        uint gasPrice,
   254	        uint timestamp,
   255	        IMessageProxyForSchain.Signature memory
   256	    )
   257	        external
   258	        override
   259	    {
   260	        require(timestamp > gasPriceTimestamp, "Gas price timestamp already updated");
   261	        require(timestamp <= block.timestamp, "Timestamp should not be in the future");
   262	        // TODO: uncomment when oracle finished
   263	        // require(
   264	        //     messageProxy.verifySignature(keccak256(abi.encodePacked(gasPrice, timestamp)), signature),
   265	        //     "Signature is not verified"
   266	        // );
   267	        emit ConstantUpdated(
   268	            keccak256(abi.encodePacked("MainnetGasPrice")),
   269	            mainnetGasPrice,
   270	            gasPrice
   271	        );
   272	        mainnetGasPrice = gasPrice;
   273	        gasPriceTimestamp = timestamp;
   274	    }

exec
/bin/bash -lc "nl -ba contracts/mainnet/DepositBoxes/DepositBoxERC20.sol | sed -n '606,780p'" in /tmp/codex-sryvig8b
 succeeded in 0ms:
   606	    /**
   607	     * @dev Retrieve tokens that were unlocked after delay for specified receiver
   608	     */
   609	    function retrieveFor(address receiver) public override {
   610	        uint256 transfersAmount = MathUpgradeable.min(
   611	            delayedTransfersByReceiver[receiver].length(),
   612	            _QUEUE_PROCESSING_LIMIT
   613	        );
   614	        uint256 currentIndex = 0;
   615	        bool retrieved = false;
   616	        uint256 countToTransfer = 0;
   617	        DelayedTransfer[] memory transfers = new DelayedTransfer[](transfersAmount);
   618	        uint256[] memory transfersIds = new uint256[](transfersAmount);
   619	        for (uint256 i = 0; i < transfersAmount; ++i) {
   620	            uint256 transferId = uint256(delayedTransfersByReceiver[receiver].at(currentIndex++));
   621	            DelayedTransfer memory transfer = delayedTransfers[transferId];
   622	            if (transfer.status != DelayedTransferStatus.COMPLETED) {
   623	                if (block.timestamp < transfer.untilTimestamp) {
   624	                    // disable detector until slither fixes false positive
   625	                    // https://github.com/crytic/slither/issues/778
   626	                    // slither-disable-next-line incorrect-equality
   627	                    if (transfer.status == DelayedTransferStatus.DELAYED) {
   628	                        break;
   629	                    } // else status is ARBITRAGE -> continue
   630	                } else { // it's time to unlock
   631	                    if (currentIndex == 1) {
   632	                        --currentIndex;
   633	                        _removeOldestDelayedTransfer(receiver);
   634	                    } else {
   635	                        delayedTransfers[transferId].status = DelayedTransferStatus.COMPLETED;
   636	                    }
   637	                    retrieved = true;
   638	                    transfers[countToTransfer] = transfer;
   639	                    transfersIds[countToTransfer] = transferId;
   640	                    ++countToTransfer;
   641	                }
   642	            } else { // status is COMPLETED
   643	                if (currentIndex == 1) {
   644	                    --currentIndex;
   645	                    retrieved = true;
   646	                    _removeOldestDelayedTransfer(receiver);
   647	                }
   648	            }
   649	        }
   650	        require(retrieved, "There are no transfers available for retrieving");
   651	        _doNTransfers(transfers, transfersIds, countToTransfer);
   652	    }
   653	
   654	    /**
   655	     * @dev Creates a new DepositBoxERC20 contract.
   656	     */
   657	    function initialize(
   658	        IContractManager contractManagerOfSkaleManagerValue,
   659	        ILinker linkerValue,
   660	        IMessageProxyForMainnet messageProxyValue
   661	    )
   662	        public
   663	        override(DepositBox, IDepositBox)
   664	        initializer
   665	    {
   666	        DepositBox.initialize(contractManagerOfSkaleManagerValue, linkerValue, messageProxyValue);
   667	    }
   668	
   669	    /**
   670	     * @dev Allows `msg.sender` to send ERC20 token from mainnet to schain to specified receiver.
   671	     *
   672	     * Requirements:
   673	     *
   674	     * - Schain name must not be `Mainnet`.
   675	     * - Receiver account on schain cannot be null.
   676	     * - Schain that receives tokens should not be killed.
   677	     * - Receiver contract should be defined.
   678	     * - `msg.sender` should approve their tokens for DepositBoxERC20 address.
   679	     */
   680	    function depositERC20Direct(
   681	        string calldata schainName,
   682	        address erc20OnMainnet,
   683	        uint256 amount,
   684	        address receiver
   685	    )
   686	        public
   687	        override
   688	        rightTransaction(schainName, receiver)
   689	        whenNotKilled(_schainHash(schainName))
   690	    {
   691	        SchainHash schainHash = _schainHash(schainName);
   692	        address contractReceiver = schainLinks[schainHash];
   693	        require(contractReceiver != address(0), "Unconnected chain");
   694	        require(
   695	            IERC20Upgradeable(erc20OnMainnet).allowance(msg.sender, address(this)) >= amount,
   696	            "DepositBox was not approved for ERC20 token"
   697	        );
   698	        bytes memory data = _receiveERC20(
   699	            schainName,
   700	            erc20OnMainnet,
   701	            receiver,
   702	            amount
   703	        );
   704	        _saveTransferredAmount(schainHash, erc20OnMainnet, amount);
   705	        IERC20MetadataUpgradeable(erc20OnMainnet).safeTransferFrom(msg.sender, address(this), amount);
   706	        messageProxy.postOutgoingMessage(
   707	            schainHash,
   708	            contractReceiver,
   709	            data
   710	        );
   711	    }
   712	
   713	    /**
   714	     * @dev Check if the receiver is in the delay whitelist
   715	     */
   716	    function isReceiverTrusted(SchainHash schainHash, address receiver) public view override returns (bool) {
   717	        return _delayConfig[schainHash].trustedReceivers.contains(receiver);
   718	    }
   719	
   720	    // private
   721	
   722	    /**
   723	     * @dev Tries to do N amount of ERC20 transfers
   724	     */
   725	    function _doNTransfers(
   726	        DelayedTransfer[] memory transfers,
   727	        uint256[] memory transfersIds,
   728	        uint256 countToTransfer
   729	    )
   730	        private
   731	    {
   732	        for (uint256 i = 0; i < countToTransfer; ++i){
   733	            DelayedTransfer memory transfer = transfers[i];
   734	            try this.doTransfer(transfer.token, transfer.receiver, transfer.amount) {
   735	                emit TransferSucceeded(transfersIds[i]);
   736	            }
   737	            catch {
   738	                emit TransferSkipped(transfersIds[i]);
   739	            }
   740	        }
   741	    }
   742	    /**
   743	     * @dev Saves amount of tokens that was transferred to schain.
   744	     */
   745	    function _saveTransferredAmount(SchainHash schainHash, address erc20Token, uint256 amount) private {
   746	        transferredAmount[schainHash][erc20Token] += amount;
   747	    }
   748	
   749	    /**
   750	     * @dev Removes amount of tokens that was transferred from schain.
   751	     */
   752	    function _removeTransferredAmount(SchainHash schainHash, address erc20Token, uint256 amount) private {
   753	        transferredAmount[schainHash][erc20Token] -= amount;
   754	    }
   755	
   756	    /**
   757	     * @dev Allows DepositBoxERC20 to receive ERC20 tokens.
   758	     *
   759	     * Emits an {ERC20TokenReady} event.
   760	     *
   761	     * Requirements:
   762	     *
   763	     * - Amount must be less than or equal to the total supply of the ERC20 contract.
   764	     * - Whitelist should be turned off for auto adding tokens to DepositBoxERC20.
   765	     */
   766	    function _receiveERC20(
   767	        string calldata schainName,
   768	        address erc20OnMainnet,
   769	        address to,
   770	        uint256 amount
   771	    )
   772	        private
   773	        returns (bytes memory data)
   774	    {
   775	        SchainHash schainHash = _schainHash(schainName);
   776	        IERC20MetadataUpgradeable erc20 = IERC20MetadataUpgradeable(erc20OnMainnet);
   777	        uint256 totalSupply = erc20.totalSupply();
   778	        require(amount <= totalSupply, "Amount is incorrect");
   779	        bool isERC20AddedToSchain = _schainToERC20[schainHash].contains(erc20OnMainnet);
   780	        if (!isERC20AddedToSchain) {

exec
/bin/bash -lc "nl -ba contracts/schain/TokenManagers/TokenManagerERC20.sol | sed -n '314,362p'" in /tmp/codex-sryvig8b
 succeeded in 0ms:
   314	    function _exit(
   315	        SchainHash chainHash,
   316	        address messageReceiver,
   317	        address contractOnMainChain,
   318	        address to,
   319	        uint256 amount
   320	    )
   321	        private
   322	    {
   323	        bool isMainChainToken;
   324	        ERC20OnChain contractOnSchain = clonesErc20[chainHash][contractOnMainChain];
   325	        if (address(contractOnSchain) == address(0)) {
   326	            contractOnSchain = ERC20OnChain(contractOnMainChain);
   327	            require(!addedClones[contractOnSchain], "Incorrect main chain token");
   328	            isMainChainToken = true;
   329	        }
   330	        require(address(contractOnSchain).isContract(), "No token clone on schain");
   331	        require(contractOnSchain.balanceOf(msg.sender) >= amount, "Insufficient funds");
   332	        require(
   333	            contractOnSchain.allowance(
   334	                msg.sender,
   335	                address(this)
   336	            ) >= amount,
   337	            "Transfer is not approved by token holder"
   338	        );
   339	        bytes memory data = Messages.encodeTransferErc20Message(address(contractOnMainChain), to, amount);
   340	        if (isMainChainToken) {
   341	            require(chainHash != MAINNET_HASH, "Main chain token could not be transferred to Mainnet");
   342	            data = _receiveERC20(
   343	                chainHash,
   344	                address(contractOnSchain),
   345	                to,
   346	                amount
   347	            );
   348	            _saveTransferredAmount(chainHash, address(contractOnSchain), amount);
   349	            require(
   350	                contractOnSchain.transferFrom(msg.sender, address(this), amount),
   351	                "Transfer was failed"
   352	            );
   353	        } else {
   354	            require(
   355	                contractOnSchain.transferFrom(msg.sender, address(this), amount),
   356	                "Transfer was failed"
   357	            );
   358	            contractOnSchain.burn(amount);
   359	        }
   360	        messageProxy.postOutgoingMessage(
   361	            chainHash,
   362	            messageReceiver,

exec
/bin/bash -lc "rg -n \"topUpReceiverBalance\\(\" contracts -g '"'!contracts/test/**'"'" in /tmp/codex-sryvig8b
 succeeded in 0ms:
contracts/schain/MessageProxyForSchain.sol:254:    function topUpReceiverBalance(address payable receiver) external override {
contracts/schain/TokenManagers/TokenManagerERC20.sol:307:        messageProxy.topUpReceiverBalance(payable(receiver));
contracts/schain/TokenManagers/TokenManagerERC721WithMetadata.sol:123:        messageProxy.topUpReceiverBalance(payable(receiver));
contracts/schain/TokenManagers/TokenManagerERC1155.sol:363:        messageProxy.topUpReceiverBalance(payable(receiver));
contracts/schain/TokenManagers/TokenManagerERC1155.sol:414:        messageProxy.topUpReceiverBalance(payable(receiver));
contracts/schain/TokenManagers/TokenManagerERC721.sol:252:        messageProxy.topUpReceiverBalance(payable(receiver));
contracts/schain/TokenManagers/TokenManagerEth.sol:85:        messageProxy.topUpReceiverBalance(payable(receiver));

exec
/bin/bash -lc "sed -n '1,220p' @openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol" in /tmp/codex-sryvig8b
 succeeded in 0ms:
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)

pragma solidity ^0.8.2;

import "../../utils/AddressUpgradeable.sol";

/**
 * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
 * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
 * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
 * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
 *
 * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
 * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
 * case an upgrade adds a module that needs to be initialized.
 *
 * For example:
 *
 * [.hljs-theme-light.nopadding]
 * ```solidity
 * contract MyToken is ERC20Upgradeable {
 *     function initialize() initializer public {
 *         __ERC20_init("MyToken", "MTK");
 *     }
 * }
 *
 * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
 *     function initializeV2() reinitializer(2) public {
 *         __ERC20Permit_init("MyToken");
 *     }
 * }
 * ```
 *
 * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
 * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
 *
 * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
 * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
 *
 * [CAUTION]
 * ====
 * Avoid leaving a contract uninitialized.
 *
 * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
 * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
 * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
 *
 * [.hljs-theme-light.nopadding]
 * ```
 * /// @custom:oz-upgrades-unsafe-allow constructor
 * constructor() {
 *     _disableInitializers();
 * }
 * ```
 * ====
 */
abstract contract Initializable {
    /**
     * @dev Indicates that the contract has been initialized.
     * @custom:oz-retyped-from bool
     */
    uint8 private _initialized;

    /**
     * @dev Indicates that the contract is in the process of being initialized.
     */
    bool private _initializing;

    /**
     * @dev Triggered when the contract has been initialized or reinitialized.
     */
    event Initialized(uint8 version);

    /**
     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
     * `onlyInitializing` functions can be used to initialize parent contracts.
     *
     * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a
     * constructor.
     *
     * Emits an {Initialized} event.
     */
    modifier initializer() {
        bool isTopLevelCall = !_initializing;
        require(
            (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),
            "Initializable: contract is already initialized"
        );
        _initialized = 1;
        if (isTopLevelCall) {
            _initializing = true;
        }
        _;
        if (isTopLevelCall) {
            _initializing = false;
            emit Initialized(1);
        }
    }

    /**
     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
     * used to initialize parent contracts.
     *
     * A reinitializer may be used after the original initialization step. This is essential to configure modules that
     * are added through upgrades and that require initialization.
     *
     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
     * cannot be nested. If one is invoked in the context of another, execution will revert.
     *
     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
     * a contract, executing them in the right order is up to the developer or operator.
     *
     * WARNING: setting the version to 255 will prevent any future reinitialization.
     *
     * Emits an {Initialized} event.
     */
    modifier reinitializer(uint8 version) {
        require(!_initializing && _initialized < version, "Initializable: contract is already initialized");
        _initialized = version;
        _initializing = true;
        _;
        _initializing = false;
        emit Initialized(version);
    }

    /**
     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
     * {initializer} and {reinitializer} modifiers, directly or indirectly.
     */
    modifier onlyInitializing() {
        require(_initializing, "Initializable: contract is not initializing");
        _;
    }

    /**
     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called
     * through proxies.
     *
     * Emits an {Initialized} event the first time it is successfully executed.
     */
    function _disableInitializers() internal virtual {
        require(!_initializing, "Initializable: contract is initializing");
        if (_initialized != type(uint8).max) {
            _initialized = type(uint8).max;
            emit Initialized(type(uint8).max);
        }
    }

    /**
     * @dev Returns the highest version that has been initialized. See {reinitializer}.
     */
    function _getInitializedVersion() internal view returns (uint8) {
        return _initialized;
    }

    /**
     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
     */
    function _isInitializing() internal view returns (bool) {
        return _initializing;
    }
}

exec
/bin/bash -lc "sed -n '1001,2000p' AUDIT_BUNDLE.txt" in /tmp/codex-sryvig8b
 succeeded in 0ms:
interface IMessageProxyForSchain is IMessageProxy {
    struct OutgoingMessageData {
        SchainHash dstChainHash; // destination chain
        uint256 msgCounter; // message counter
        address srcContract; // origin
        address dstContract; // receiver
        bytes data; // payload
    }

    function initialize(IKeyStorage blsKeyStorage, string memory schainName) external;
    function setMinimumReceiverBalance(uint256 balance) external;
    function topUpReceiverBalance(address payable receiver) external;
    function messageInProgress() external view returns (bool);
    function verifyOutgoingMessageData(OutgoingMessageData memory message) external view returns (bool);
    function verifySignature(bytes32 hashedMessage, Signature memory signature) external view returns (bool);
}

================================================================================
FILE: @skalenetwork/ima-interfaces/schain/ITokenManager.sol
================================================================================
// SPDX-License-Identifier: AGPL-3.0-only

/**
 *   ITokenManager - SKALE Interchain Messaging Agent
 *   Copyright (C) 2021-Present SKALE Labs
 *   @author Dmytro Stebaiev
 *
 *   SKALE IMA is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published
 *   by the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   SKALE IMA is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with SKALE IMA.  If not, see <https://www.gnu.org/licenses/>.
 */

pragma solidity >=0.8.19 <0.9.0;

import "../IMessageReceiver.sol";


interface ITokenManager is IMessageReceiver {
    function enableAutomaticDeploy() external;
    function addTokenManager(string calldata schainName, address newTokenManager) external;
    function removeTokenManager(string calldata schainName) external;
    function hasTokenManager(string calldata schainName) external view returns (bool);
}

================================================================================
FILE: @skalenetwork/ima-interfaces/schain/ITokenManagerLinker.sol
================================================================================
// SPDX-License-Identifier: AGPL-3.0-only

/**
 *   ITokenManagerLinker - SKALE Interchain Messaging Agent
 *   Copyright (C) 2021-Present SKALE Labs
 *   @author Dmytro Stebaiev
 *
 *   SKALE IMA is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published
 *   by the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   SKALE IMA is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with SKALE IMA.  If not, see <https://www.gnu.org/licenses/>.
 */

pragma solidity >=0.8.19 <0.9.0;

import "./IMessageProxyForSchain.sol";
import "./ITokenManager.sol";


interface ITokenManagerLinker {
    function connectSchain(string calldata schainName) external;
    function disconnectSchain(string calldata schainName) external;
    function initialize(IMessageProxyForSchain newMessageProxyAddress, address linker) external;
    function registerTokenManager(ITokenManager newTokenManager) external;
    function removeTokenManager(ITokenManager tokenManagerAddress) external;
    function hasSchain(string calldata schainName) external view returns (bool connected);
    function hasTokenManager(address tokenManager) external view returns (bool);
}

================================================================================
FILE: @skalenetwork/ima-interfaces/schain/TokenManagers/ITokenContractManager.sol
================================================================================
// SPDX-License-Identifier: AGPL-3.0-only

/**
 *   ITokenManagerERC20 - SKALE Interchain Messaging Agent
 *   Copyright (C) 2021-Present SKALE Labs
 *   @author Dmytro Stebaiev
 *
 *   SKALE IMA is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published
 *   by the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   SKALE IMA is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with SKALE IMA.  If not, see <https://www.gnu.org/licenses/>.
 */

pragma solidity >=0.8.19 <0.9.0;

import "../ICommunityLocker.sol";
import "../IMessageProxyForSchain.sol";
import "../ITokenManager.sol";
import "../ITokenManagerLinker.sol";

interface ITokenContractManager is ITokenManager {
    function initialize(
        string memory newChainName,
        IMessageProxyForSchain newMessageProxy,
        ITokenManagerLinker newIMALinker,
        ICommunityLocker newCommunityLocker,
        address newDepositBox
    ) external;
}

================================================================================
FILE: @skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC1155.sol
================================================================================
// SPDX-License-Identifier: AGPL-3.0-only

/**
 *   ITokenManagerERC1155 - SKALE Interchain Messaging Agent
 *   Copyright (C) 2021-Present SKALE Labs
 *   @author Dmytro Stebaiev
 *
 *   SKALE IMA is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published
 *   by the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   SKALE IMA is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with SKALE IMA.  If not, see <https://www.gnu.org/licenses/>.
 */

pragma solidity >=0.8.19 <0.9.0;

import "./ITokenContractManager.sol";


interface ITokenManagerERC1155 is ITokenContractManager {
    function exitToMainERC1155(
        address contractOnMainnet,
        uint256 id,
        uint256 amount
    ) external;
    function exitToMainERC1155Batch(
        address contractOnMainnet,
        uint256[] memory ids,
        uint256[] memory amounts
    ) external;
    function transferToSchainERC1155(
        string calldata targetSchainName,
        address contractOnMainnet,
        uint256 id,
        uint256 amount
    ) external;
    function transferToSchainERC1155Batch(
        string calldata targetSchainName,
        address contractOnMainnet,
        uint256[] memory ids,
        uint256[] memory amounts
    ) external;
    function addERC1155TokenByOwner(
        string calldata targetChainName,
        address erc1155OnMainnet,
        address erc1155OnSchain
    ) external;
}

================================================================================
FILE: @skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC20.sol
================================================================================
// SPDX-License-Identifier: AGPL-3.0-only

/**
 *   ITokenManagerERC20 - SKALE Interchain Messaging Agent
 *   Copyright (C) 2021-Present SKALE Labs
 *   @author Dmytro Stebaiev
 *
 *   SKALE IMA is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published
 *   by the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   SKALE IMA is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with SKALE IMA.  If not, see <https://www.gnu.org/licenses/>.
 */

pragma solidity >=0.8.19 <0.9.0;

import "./ITokenContractManager.sol";

interface ITokenManagerERC20 is ITokenContractManager {
    function exitToMainERC20(
        address contractOnMainnet,
        uint256 amount
    ) external;
    function transferToSchainERC20(
        string calldata targetSchainName,
        address contractOnMainnet,
        uint256 amount
    ) external;
    function transferToSchainERC20Direct(
        string calldata targetSchainName,
        address contractOnMainnet,
        uint256 amount,
        address to
    ) external;
    function transferToSchainHashERC20Direct(
        SchainHash targetSchainHash,
        address contractOnMainnet,
        uint256 amount,
        address receiver
    ) external;
    function addERC20TokenByOwner(
        string calldata targetChainName,
        address erc20OnMainnet,
        address erc20OnSchain
    ) external;
}

================================================================================
FILE: @skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerERC721.sol
================================================================================
// SPDX-License-Identifier: AGPL-3.0-only

/**
 *   ITokenManagerERC721 - SKALE Interchain Messaging Agent
 *   Copyright (C) 2021-Present SKALE Labs
 *   @author Dmytro Stebaiev
 *
 *   SKALE IMA is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published
 *   by the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   SKALE IMA is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with SKALE IMA.  If not, see <https://www.gnu.org/licenses/>.
 */

pragma solidity >=0.8.19 <0.9.0;

import "./ITokenContractManager.sol";

interface ITokenManagerERC721 is ITokenContractManager {
    function exitToMainERC721(address contractOnMainnet, uint256 tokenId) external;
    function transferToSchainERC721(
        string calldata targetSchainName,
        address contractOnMainnet,
        uint256 tokenId
    ) external;
    function addERC721TokenByOwner(
        string calldata targetChainName,
        address erc721OnMainnet,
        address erc721OnSchain
    ) external;
}

================================================================================
FILE: @skalenetwork/ima-interfaces/schain/TokenManagers/ITokenManagerEth.sol
================================================================================
// SPDX-License-Identifier: AGPL-3.0-only

/**
 *   ITokenManagerEth - SKALE Interchain Messaging Agent
 *   Copyright (C) 2021-Present SKALE Labs
 *   @author Dmytro Stebaiev
 *
 *   SKALE IMA is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published
 *   by the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   SKALE IMA is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with SKALE IMA.  If not, see <https://www.gnu.org/licenses/>.
 */

pragma solidity >=0.8.19 <0.9.0;

import "../tokens/IEthErc20.sol";
import "../ICommunityLocker.sol";
import "../IMessageProxyForSchain.sol";
import "../ITokenManager.sol";
import "../ITokenManagerLinker.sol";


interface ITokenManagerEth is ITokenManager {
    function initialize(
        string memory newChainName,
        IMessageProxyForSchain newMessageProxy,
        ITokenManagerLinker newIMALinker,
        ICommunityLocker newCommunityLocker,
        address newDepositBox,
        IEthErc20 ethErc20Address
    ) external;
    function setEthErc20Address(IEthErc20 newEthErc20Address) external;
    function exitToMain(uint256 amount) external;
}

================================================================================
FILE: @skalenetwork/ima-interfaces/schain/bls/IFieldOperations.sol
================================================================================
// SPDX-License-Identifier: AGPL-3.0-only

/**
 *   IFieldOperations.sol - SKALE Interchain Messaging Agent
 *   Copyright (C) 2021-Present SKALE Labs
 *   @author Dmytro Stebaiev
 *
 *   SKALE IMA is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published
 *   by the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   SKALE IMA is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with SKALE IMA.  If not, see <https://www.gnu.org/licenses/>.
 */

pragma solidity >=0.8.19 <0.9.0;


interface IFieldOperations {

    /**
     * @dev Structure that represents the field element { a + ib }
     */
    struct Fp2Point {
        uint a;
        uint b;
    }

    /**
     * @dev Structure that represents an element of G2
     */
    struct G2Point {
        Fp2Point x;
        Fp2Point y;
    }
}

================================================================================
FILE: @skalenetwork/ima-interfaces/schain/tokens/IERC1155OnChain.sol
================================================================================
// SPDX-License-Identifier: AGPL-3.0-only

/**
 *   IERC1155OnChain - SKALE Interchain Messaging Agent
 *   Copyright (C) 2021-Present SKALE Labs
 *   @author Dmytro Stebaiev
 *
 *   SKALE IMA is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published
 *   by the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   SKALE IMA is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with SKALE IMA.  If not, see <https://www.gnu.org/licenses/>.
 */

pragma solidity >=0.8.19 <0.9.0;


interface IERC1155OnChain {
    function mint(
        address account,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) external;
    function mintBatch(
        address account,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) external;
}

================================================================================
FILE: @skalenetwork/ima-interfaces/schain/tokens/IERC20OnChain.sol
================================================================================
// SPDX-License-Identifier: AGPL-3.0-only

/**
 *   IERC20OnChain - SKALE Interchain Messaging Agent
 *   Copyright (C) 2021-Present SKALE Labs
 *   @author Dmytro Stebaiev
 *
 *   SKALE IMA is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published
 *   by the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   SKALE IMA is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with SKALE IMA.  If not, see <https://www.gnu.org/licenses/>.
 */

pragma solidity >=0.8.19 <0.9.0;


interface IERC20OnChain {
    function mint(address account, uint256 value) external;
}

================================================================================
FILE: @skalenetwork/ima-interfaces/schain/tokens/IERC721OnChain.sol
================================================================================
// SPDX-License-Identifier: AGPL-3.0-only

/**
 *   IERC721OnChain - SKALE Interchain Messaging Agent
 *   Copyright (C) 2021-Present SKALE Labs
 *   @author Dmytro Stebaiev
 *
 *   SKALE IMA is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published
 *   by the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   SKALE IMA is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with SKALE IMA.  If not, see <https://www.gnu.org/licenses/>.
 */

pragma solidity >=0.8.19 <0.9.0;


interface IERC721OnChain {
    function setTokenURI(uint256 tokenId, string calldata tokenUri) external returns (bool);
    function mint(address account, uint256 tokenId) external;
}

================================================================================
FILE: @skalenetwork/ima-interfaces/schain/tokens/IEthErc20.sol
================================================================================
// SPDX-License-Identifier: AGPL-3.0-only

/**
 *   IEthErc20 - SKALE Interchain Messaging Agent
 *   Copyright (C) 2021-Present SKALE Labs
 *   @author Dmytro Stebaiev
 *
 *   SKALE IMA is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published
 *   by the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   SKALE IMA is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with SKALE IMA.  If not, see <https://www.gnu.org/licenses/>.
 */

pragma solidity >=0.8.19 <0.9.0;


interface IEthErc20 {
    function mint(address account, uint256 amount) external;
    function forceBurn(address account, uint256 amount) external;
    function initialize(address tokenManagerEthAddress) external;
}

================================================================================
FILE: @skalenetwork/skale-manager-interfaces/IContractManager.sol
================================================================================
// SPDX-License-Identifier: AGPL-3.0-only

/*
    IContractManager.sol - SKALE Manager Interfaces
    Copyright (C) 2021-Present SKALE Labs
    @author Dmytro Stebaeiv

    SKALE Manager Interfaces is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published
    by the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    SKALE Manager Interfaces is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with SKALE Manager Interfaces.  If not, see <https://www.gnu.org/licenses/>.
*/

pragma solidity >=0.6.10 <0.9.0;

interface IContractManager {
    /**
     * @dev Emitted when contract is upgraded.
     */
    event ContractUpgraded(string contractsName, address contractsAddress);

    function initialize() external;
    function setContractsAddress(string calldata contractsName, address newContractsAddress) external;
    function contracts(bytes32 nameHash) external view returns (address);
    function getDelegationPeriodManager() external view returns (address);
    function getBounty() external view returns (address);
    function getValidatorService() external view returns (address);
    function getTimeHelpers() external view returns (address);
    function getConstantsHolder() external view returns (address);
    function getSkaleToken() external view returns (address);
    function getTokenState() external view returns (address);
    function getPunisher() external view returns (address);
    function getContract(string calldata name) external view returns (address);
}

================================================================================
FILE: @skalenetwork/skale-manager-interfaces/INodes.sol
================================================================================
// SPDX-License-Identifier: AGPL-3.0-only

/*
    INodes.sol - SKALE Manager
    Copyright (C) 2018-Present SKALE Labs
    @author Artem Payvin

    SKALE Manager is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published
    by the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    SKALE Manager is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with SKALE Manager.  If not, see <https://www.gnu.org/licenses/>.
*/

pragma solidity >=0.6.10 <0.9.0;

import "./utils/IRandom.sol";

interface INodes {
    // All Nodes states
    enum NodeStatus {Active, Leaving, Left, In_Maintenance}

    struct Node {
        string name;
        bytes4 ip;
        bytes4 publicIP;
        uint16 port;
        bytes32[2] publicKey;
        uint startBlock;
        uint lastRewardDate;
        uint finishTime;
        NodeStatus status;
        uint validatorId;
    }

    // struct to note which Nodes and which number of Nodes owned by user
    struct CreatedNodes {
        mapping (uint => bool) isNodeExist;
        uint numberOfNodes;
    }

    struct SpaceManaging {
        uint8 freeSpace;
        uint indexInSpaceMap;
    }

    struct NodeCreationParams {
        string name;
        bytes4 ip;
        bytes4 publicIp;
        uint16 port;
        bytes32[2] publicKey;
        uint16 nonce;
        string domainName;
    }
    
    /**
     * @dev Emitted when a node is created.
     */
    event NodeCreated(
        uint nodeIndex,
        address owner,
        string name,
        bytes4 ip,
        bytes4 publicIP,
        uint16 port,
        uint16 nonce,
        string domainName
    );

    /**
     * @dev Emitted when a node completes a network exit.
     */
    event ExitCompleted(
        uint nodeIndex
    );

    /**
     * @dev Emitted when a node begins to exit from the network.
     */
    event ExitInitialized(
        uint nodeIndex,
        uint startLeavingPeriod
    );

    /**
     * @dev Emitted when a node set to in compliant or compliant.
     */
    event IncompliantNode(
        uint indexed nodeIndex,
        bool status
    );

    /**
     * @dev Emitted when a node set to in maintenance or from in maintenance.
     */
    event MaintenanceNode(
        uint indexed nodeIndex,
        bool status
    );

    /**
     * @dev Emitted when a node status changed.
     */
    event IPChanged(
        uint indexed nodeIndex,
        bytes4 previousIP,
        bytes4 newIP
    );
    
    function removeSpaceFromNode(uint nodeIndex, uint8 space) external returns (bool);
    function addSpaceToNode(uint nodeIndex, uint8 space) external;
    function changeNodeLastRewardDate(uint nodeIndex) external;
    function changeNodeFinishTime(uint nodeIndex, uint time) external;
    function createNode(address from, NodeCreationParams calldata params) external;
    function initExit(uint nodeIndex) external;
    function completeExit(uint nodeIndex) external returns (bool);
    function deleteNodeForValidator(uint validatorId, uint nodeIndex) external;
    function checkPossibilityCreatingNode(address nodeAddress) external;
    function checkPossibilityToMaintainNode(uint validatorId, uint nodeIndex) external returns (bool);
    function setNodeInMaintenance(uint nodeIndex) external;
    function removeNodeFromInMaintenance(uint nodeIndex) external;
    function setNodeIncompliant(uint nodeIndex) external;
    function setNodeCompliant(uint nodeIndex) external;
    function setDomainName(uint nodeIndex, string memory domainName) external;
    function makeNodeVisible(uint nodeIndex) external;
    function makeNodeInvisible(uint nodeIndex) external;
    function changeIP(uint nodeIndex, bytes4 newIP, bytes4 newPublicIP) external;
    function numberOfActiveNodes() external view returns (uint);
    function incompliant(uint nodeIndex) external view returns (bool);
    function getRandomNodeWithFreeSpace(
        uint8 freeSpace,
        IRandom.RandomGenerator memory randomGenerator
    )
        external
        view
        returns (uint);
    function isTimeForReward(uint nodeIndex) external view returns (bool);
    function getNodeIP(uint nodeIndex) external view returns (bytes4);
    function getNodeDomainName(uint nodeIndex) external view returns (string memory);
    function getNodePort(uint nodeIndex) external view returns (uint16);
    function getNodePublicKey(uint nodeIndex) external view returns (bytes32[2] memory);
    function getNodeAddress(uint nodeIndex) external view returns (address);
    function getNodeFinishTime(uint nodeIndex) external view returns (uint);
    function isNodeLeft(uint nodeIndex) external view returns (bool);
    function isNodeInMaintenance(uint nodeIndex) external view returns (bool);
    function getNodeLastRewardDate(uint nodeIndex) external view returns (uint);
    function getNodeNextRewardDate(uint nodeIndex) external view returns (uint);
    function getNumberOfNodes() external view returns (uint);
    function getNumberOnlineNodes() external view returns (uint);
    function getActiveNodeIds() external view returns (uint[] memory activeNodeIds);
    function getNodeStatus(uint nodeIndex) external view returns (NodeStatus);
    function getValidatorNodeIndexes(uint validatorId) external view returns (uint[] memory);
    function countNodesWithFreeSpace(uint8 freeSpace) external view returns (uint count);
    function getValidatorId(uint nodeIndex) external view returns (uint);
    function isNodeExist(address from, uint nodeIndex) external view returns (bool);
    function isNodeActive(uint nodeIndex) external view returns (bool);
    function isNodeLeaving(uint nodeIndex) external view returns (bool);
}

================================================================================
FILE: @skalenetwork/skale-manager-interfaces/ISchains.sol
================================================================================
// SPDX-License-Identifier: AGPL-3.0-only

/*
    ISchains.sol - SKALE Manager Interfaces
    Copyright (C) 2021-Present SKALE Labs
    @author Dmytro Stebaeiv

    SKALE Manager Interfaces is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published
    by the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    SKALE Manager Interfaces is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with SKALE Manager Interfaces.  If not, see <https://www.gnu.org/licenses/>.
*/

pragma solidity >=0.6.10 <0.9.0;

interface ISchains {

    struct SchainOption {
        string name;
        bytes value;
    }
    
    /**
     * @dev Emitted when an schain is created.
     */
    event SchainCreated(
        string name,
        address owner,
        uint partOfNode,
        uint lifetime,
        uint numberOfNodes,
        uint deposit,
        uint16 nonce,
        bytes32 schainHash
    );

    /**
     * @dev Emitted when an schain is deleted.
     */
    event SchainDeleted(
        address owner,
        string name,
        bytes32 indexed schainHash
    );

    /**
     * @dev Emitted when a node in an schain is rotated.
     */
    event NodeRotated(
        bytes32 schainHash,
        uint oldNode,
        uint newNode
    );

    /**
     * @dev Emitted when a node is added to an schain.
     */
    event NodeAdded(
        bytes32 schainHash,
        uint newNode
    );

    /**
     * @dev Emitted when a group of nodes is created for an schain.
     */
    event SchainNodes(
        string name,
        bytes32 schainHash,
        uint[] nodesInGroup
    );

    function addSchain(address from, uint deposit, bytes calldata data) external;
    function addSchainByFoundation(
        uint lifetime,
        uint8 typeOfSchain,
        uint16 nonce,
        string calldata name,
        address schainOwner,
        address schainOriginator,
        SchainOption[] calldata options
    )
        external
        payable;
    function deleteSchain(address from, string calldata name) external;
    function deleteSchainByRoot(string calldata name) external;
    function restartSchainCreation(string calldata name) external;
    function verifySchainSignature(
        uint256 signA,
        uint256 signB,
        bytes32 hash,
        uint256 counter,
        uint256 hashA,
        uint256 hashB,
        string calldata schainName
    )
        external
        view
        returns (bool);
    function getSchainPrice(uint typeOfSchain, uint lifetime) external view returns (uint);
    function getOption(bytes32 schainHash, string calldata optionName) external view returns (bytes memory);
    function getOptions(bytes32 schainHash) external view returns (SchainOption[] memory);
}

================================================================================
FILE: @skalenetwork/skale-manager-interfaces/ISchainsInternal.sol
================================================================================
// SPDX-License-Identifier: AGPL-3.0-only

/*
    ISchainsInternal - SKALE Manager Interfaces
    Copyright (C) 2021-Present SKALE Labs
    @author Dmytro Stebaeiv

    SKALE Manager Interfaces is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published
    by the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    SKALE Manager Interfaces is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with SKALE Manager Interfaces.  If not, see <https://www.gnu.org/licenses/>.
*/

pragma solidity >=0.6.10 <0.9.0;

import "./INodes.sol";

interface ISchainsInternal {
    struct Schain {
        string name;
        address owner;
        uint indexInOwnerList;
        uint8 partOfNode;
        uint lifetime;
        uint startDate;
        uint startBlock;
        uint deposit;
        uint64 index;
        uint generation;
        address originator;
    }

    struct SchainType {
        uint8 partOfNode;
        uint numberOfNodes;
    }

    /**
     * @dev Emitted when schain type added.
     */
    event SchainTypeAdded(uint indexed schainType, uint partOfNode, uint numberOfNodes);

    /**
     * @dev Emitted when schain type removed.
     */
    event SchainTypeRemoved(uint indexed schainType);

    function initializeSchain(
        string calldata name,
        address from,
        address originator,
        uint lifetime,
        uint deposit) external;
    function createGroupForSchain(
        bytes32 schainHash,
        uint numberOfNodes,
        uint8 partOfNode
    )
        external
        returns (uint[] memory);
    function changeLifetime(bytes32 schainHash, uint lifetime, uint deposit) external;
    function removeSchain(bytes32 schainHash, address from) external;
    function removeNodeFromSchain(uint nodeIndex, bytes32 schainHash) external;
    function deleteGroup(bytes32 schainHash) external;
    function setException(bytes32 schainHash, uint nodeIndex) external;
    function setNodeInGroup(bytes32 schainHash, uint nodeIndex) external;
    function removeHolesForSchain(bytes32 schainHash) external;
    function addSchainType(uint8 partOfNode, uint numberOfNodes) external;
    function removeSchainType(uint typeOfSchain) external;
    function setNumberOfSchainTypes(uint newNumberOfSchainTypes) external;
    function removeNodeFromAllExceptionSchains(uint nodeIndex) external;
    function removeAllNodesFromSchainExceptions(bytes32 schainHash) external;
    function makeSchainNodesInvisible(bytes32 schainHash) external;
    function makeSchainNodesVisible(bytes32 schainHash) external;
    function newGeneration() external;
    function addSchainForNode(INodes nodes,uint nodeIndex, bytes32 schainHash) external;
    function removeSchainForNode(uint nodeIndex, uint schainIndex) external;
    function removeNodeFromExceptions(bytes32 schainHash, uint nodeIndex) external;
    function isSchainActive(bytes32 schainHash) external view returns (bool);
    function schainsAtSystem(uint index) external view returns (bytes32);
    function numberOfSchains() external view returns (uint64);
    function getSchains() external view returns (bytes32[] memory);
    function getSchainsPartOfNode(bytes32 schainHash) external view returns (uint8);
    function getSchainListSize(address from) external view returns (uint);
    function getSchainHashesByAddress(address from) external view returns (bytes32[] memory);
    function getSchainHashesForNode(uint nodeIndex) external view returns (bytes32[] memory);
    function getSchainOwner(bytes32 schainHash) external view returns (address);
    function getSchainOriginator(bytes32 schainHash) external view returns (address);
    function isSchainNameAvailable(string calldata name) external view returns (bool);
    function isTimeExpired(bytes32 schainHash) external view returns (bool);
    function isOwnerAddress(address from, bytes32 schainHash) external view returns (bool);
    function getSchainName(bytes32 schainHash) external view returns (string memory);
    function getActiveSchain(uint nodeIndex) external view returns (bytes32);
    function getActiveSchains(uint nodeIndex) external view returns (bytes32[] memory activeSchains);
    function getNumberOfNodesInGroup(bytes32 schainHash) external view returns (uint);
    function getNodesInGroup(bytes32 schainHash) external view returns (uint[] memory);
    function isNodeAddressesInGroup(bytes32 schainHash, address sender) external view returns (bool);
    function getNodeIndexInGroup(bytes32 schainHash, uint nodeHash) external view returns (uint);
    function isAnyFreeNode(bytes32 schainHash) external view returns (bool);
    function checkException(bytes32 schainHash, uint nodeIndex) external view returns (bool);
    function checkHoleForSchain(bytes32 schainHash, uint indexOfNode) external view returns (bool);
    function checkSchainOnNode(uint nodeIndex, bytes32 schainHash) external view returns (bool);
    function getSchainType(uint typeOfSchain) external view returns(uint8, uint);
    function getGeneration(bytes32 schainHash) external view returns (uint);
    function isSchainExist(bytes32 schainHash) external view returns (bool);
}

================================================================================
FILE: @skalenetwork/skale-manager-interfaces/IWallets.sol
================================================================================
// SPDX-License-Identifier: AGPL-3.0-only

/*
    IWallets - SKALE Manager Interfaces
    Copyright (C) 2021-Present SKALE Labs
    @author Dmytro Stebaeiv

    SKALE Manager Interfaces is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published
    by the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    SKALE Manager Interfaces is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with SKALE Manager Interfaces.  If not, see <https://www.gnu.org/licenses/>.
*/

pragma solidity >=0.6.10 <0.9.0;

interface IWallets {
    receive() external payable;
    function refundGasByValidator(uint validatorId, address payable spender, uint gasLimit) external;
    function refundGasByValidatorToSchain(uint validatorId, bytes32 schainHash) external;

I’ve traced the bridge/accounting paths on mainnet and schain side. Two concrete loss-of-funds paths are standing out: ERC20 amount accounting trusts nominal transfers, and delayed ERC20 payouts clear claims before confirming token delivery.
  ✓ Read AUDIT_BUNDLE.txt completely and map first-party contracts plus trust boundaries
  → Inspect high-risk flows: message verification, token/ETH deposit-withdraw paths, external calls, and upgradeable init/access patterns
  • Assemble concrete exploit findings with file/line references and emit JSON
Findings are assembled. I’m formatting the final audit output as schema-valid JSON now.
  ✓ Read AUDIT_BUNDLE.txt completely and map first-party contracts plus trust boundaries
  ✓ Inspect high-risk flows: message verification, token/ETH deposit-withdraw paths, external calls, and upgradeable init/access patterns
  → Assemble concrete exploit findings with file/line references and emit JSON
codex
{"no_findings":false,"summary":"Found a high-severity ERC20 accounting break on lock, a medium-severity delayed-withdrawal claim-loss bug, and a low-severity unauthenticated oracle setter.","findings":[{"severity":"high","category":"other","title":"ERC20 bridge accounting trusts the requested amount instead of the amount actually received","exploit_scenario":"A user bridges a fee-on-transfer or deflationary ERC20. `DepositBoxERC20` records and messages the full `amount` before/without checking how many tokens the bridge actually received. The destination chain credits the full amount, but the source bridge locked less. The attacker can later exit the full credited balance and drain other users' liquidity or leave the bridge permanently undercollateralized. The same nominal-amount assumption exists in the schain-native ERC20 path when a token is locked for schain-to-schain transfer.","recommendation":"Measure `balanceBefore`/`balanceAfter` around every ERC20 pull and bridge only the actual received amount. Revert if the received amount is smaller than requested unless the token type is explicitly unsupported. Apply the same balance-delta accounting anywhere ERC20s are locked rather than burned.","evidence":"On mainnet, the code builds the outbound message and increments `transferredAmount` using the caller-supplied `amount`, then performs `safeTransferFrom` with no balance-delta check. On schain-native ERC20 transfers, `_saveTransferredAmount(..., amount)` is also done before `transferFrom`, again assuming the nominal amount was received.","locations":["contracts/mainnet/DepositBoxes/DepositBoxERC20.sol:698","contracts/mainnet/DepositBoxes/DepositBoxERC20.sol:704","contracts/mainnet/DepositBoxes/DepositBoxERC20.sol:705","contracts/schain/TokenManagers/TokenManagerERC20.sol:339","contracts/schain/TokenManagers/TokenManagerERC20.sol:348","contracts/schain/TokenManagers/TokenManagerERC20.sol:350"]},{"severity":"medium","category":"other","title":"Delayed ERC20 withdrawals clear user claims before confirming token delivery","exploit_scenario":"When a delayed transfer becomes withdrawable, `retrieveFor` marks it completed or deletes it from the queue before attempting the ERC20 transfer. If the token transfer then fails, the call is swallowed and only `TransferSkipped` is emitted. A token admin can pause or blacklist transfers right before unlock, or a nonstandard token can fail transfer, causing the receiver's claim to be irreversibly erased while the tokens remain stuck in the bridge contract.","recommendation":"Do not mutate delayed-transfer state until the token transfer succeeds. Revert failed payouts, or leave the transfer pending so the user can retry later. If partial progress is needed, persist an explicit failed state with an admin/user recovery path instead of deleting the claim.","evidence":"`retrieveFor` removes or marks transfers as `COMPLETED` before calling `_doNTransfers`. `_doNTransfers` catches transfer failures and only emits `TransferSkipped`, without restoring the queue entry or status.","locations":["contracts/mainnet/DepositBoxes/DepositBoxERC20.sol:631","contracts/mainnet/DepositBoxes/DepositBoxERC20.sol:635","contracts/mainnet/DepositBoxes/DepositBoxERC20.sol:651","contracts/mainnet/DepositBoxes/DepositBoxERC20.sol:734","contracts/mainnet/DepositBoxes/DepositBoxERC20.sol:737"]},{"severity":"low","category":"oracle","title":"`CommunityLocker.setGasPrice` accepts arbitrary caller-supplied oracle values","exploit_scenario":"Any account can update `mainnetGasPrice` and `gasPriceTimestamp` by calling `setGasPrice`; the signature parameter is unused and the verification check is commented out. Today this state is not consumed elsewhere in first-party code, so impact is limited, but if operators or future upgrades rely on it, an attacker can feed arbitrary prices and timestamps.","recommendation":"Require a verified signature or strict role-based authorization before updating oracle state. If the oracle is not live yet, disable the entrypoint rather than accepting unauthenticated writes.","evidence":"The function has no access-control modifier, the signature argument is unnamed/unused, and the intended `messageProxy.verifySignature(...)` check is commented out.","locations":["contracts/schain/CommunityLocker.sol:252","contracts/schain/CommunityLocker.sol:257","contracts/schain/CommunityLocker.sol:262","contracts/schain/CommunityLocker.sol:272"]}]}
tokens used
616,442
Metadata
{
    "codex": {
        "ran_at": "2026-04-04T04:25:38.615660+00:00",
        "returncode": 0
    },
    "project": {
        "mode": "source",
        "file_count": 143,
        "import_count": 168,
        "first_party_contracts_count": 105
    },
    "summary": "Found a high-severity ERC20 accounting break on lock, a medium-severity delayed-withdrawal claim-loss bug, and a low-severity unauthenticated oracle setter.",
    "raw_final": {
        "summary": "Found a high-severity ERC20 accounting break on lock, a medium-severity delayed-withdrawal claim-loss bug, and a low-severity unauthenticated oracle setter.",
        "findings": [
            {
                "title": "ERC20 bridge accounting trusts the requested amount instead of the amount actually received",
                "category": "other",
                "evidence": "On mainnet, the code builds the outbound message and increments `transferredAmount` using the caller-supplied `amount`, then performs `safeTransferFrom` with no balance-delta check. On schain-native ERC20 transfers, `_saveTransferredAmount(..., amount)` is also done before `transferFrom`, again assuming the nominal amount was received.",
                "severity": "high",
                "locations": [
                    "contracts/mainnet/DepositBoxes/DepositBoxERC20.sol:698",
                    "contracts/mainnet/DepositBoxes/DepositBoxERC20.sol:704",
                    "contracts/mainnet/DepositBoxes/DepositBoxERC20.sol:705",
                    "contracts/schain/TokenManagers/TokenManagerERC20.sol:339",
                    "contracts/schain/TokenManagers/TokenManagerERC20.sol:348",
                    "contracts/schain/TokenManagers/TokenManagerERC20.sol:350"
                ],
                "recommendation": "Measure `balanceBefore`/`balanceAfter` around every ERC20 pull and bridge only the actual received amount. Revert if the received amount is smaller than requested unless the token type is explicitly unsupported. Apply the same balance-delta accounting anywhere ERC20s are locked rather than burned.",
                "exploit_scenario": "A user bridges a fee-on-transfer or deflationary ERC20. `DepositBoxERC20` records and messages the full `amount` before/without checking how many tokens the bridge actually received. The destination chain credits the full amount, but the source bridge locked less. The attacker can later exit the full credited balance and drain other users' liquidity or leave the bridge permanently undercollateralized. The same nominal-amount assumption exists in the schain-native ERC20 path when a token is locked for schain-to-schain transfer."
            },
            {
                "title": "Delayed ERC20 withdrawals clear user claims before confirming token delivery",
                "category": "other",
                "evidence": "`retrieveFor` removes or marks transfers as `COMPLETED` before calling `_doNTransfers`. `_doNTransfers` catches transfer failures and only emits `TransferSkipped`, without restoring the queue entry or status.",
                "severity": "medium",
                "locations": [
                    "contracts/mainnet/DepositBoxes/DepositBoxERC20.sol:631",
                    "contracts/mainnet/DepositBoxes/DepositBoxERC20.sol:635",
                    "contracts/mainnet/DepositBoxes/DepositBoxERC20.sol:651",
                    "contracts/mainnet/DepositBoxes/DepositBoxERC20.sol:734",
                    "contracts/mainnet/DepositBoxes/DepositBoxERC20.sol:737"
                ],
                "recommendation": "Do not mutate delayed-transfer state until the token transfer succeeds. Revert failed payouts, or leave the transfer pending so the user can retry later. If partial progress is needed, persist an explicit failed state with an admin/user recovery path instead of deleting the claim.",
                "exploit_scenario": "When a delayed transfer becomes withdrawable, `retrieveFor` marks it completed or deletes it from the queue before attempting the ERC20 transfer. If the token transfer then fails, the call is swallowed and only `TransferSkipped` is emitted. A token admin can pause or blacklist transfers right before unlock, or a nonstandard token can fail transfer, causing the receiver's claim to be irreversibly erased while the tokens remain stuck in the bridge contract."
            },
            {
                "title": "`CommunityLocker.setGasPrice` accepts arbitrary caller-supplied oracle values",
                "category": "oracle",
                "evidence": "The function has no access-control modifier, the signature argument is unnamed/unused, and the intended `messageProxy.verifySignature(...)` check is commented out.",
                "severity": "low",
                "locations": [
                    "contracts/schain/CommunityLocker.sol:252",
                    "contracts/schain/CommunityLocker.sol:257",
                    "contracts/schain/CommunityLocker.sol:262",
                    "contracts/schain/CommunityLocker.sol:272"
                ],
                "recommendation": "Require a verified signature or strict role-based authorization before updating oracle state. If the oracle is not live yet, disable the entrypoint rather than accepting unauthenticated writes.",
                "exploit_scenario": "Any account can update `mainnetGasPrice` and `gasPriceTimestamp` by calling `setGasPrice`; the signature parameter is unused and the verification check is commented out. Today this state is not consumed elsewhere in first-party code, so impact is limited, but if operators or future upgrades rely on it, an attacker can feed arbitrary prices and timestamps."
            }
        ],
        "no_findings": false
    },
    "no_findings": false,
    "schema_version": 1
}

Opcode Heuristics

tool.cast_disasm
Delegatecall
0
Selfdestruct
0
CREATE2
0
CALL-family (heavy)
10
EXT*/BALANCE
8
Total opcodes
6807
Flags
heavy_ext_balance_usage
View cast disassembly output
00000000: PUSH1 0x80
00000002: PUSH1 0x40
00000004: MSTORE
00000005: PUSH1 0x04
00000007: CALLDATASIZE
00000008: LT
00000009: PUSH2 0x020f
0000000c: JUMPI
0000000d: PUSH1 0x00
0000000f: CALLDATALOAD
00000010: PUSH1 0xe0
00000012: SHR
00000013: DUP1
00000014: PUSH4 0x6cfc7d64
00000019: GT
0000001a: PUSH2 0x0118
0000001d: JUMPI
0000001e: DUP1
0000001f: PUSH4 0xb0cba84e
00000024: GT
00000025: PUSH2 0x00a0
00000028: JUMPI
00000029: DUP1
0000002a: PUSH4 0xc80493cf
0000002f: GT
00000030: PUSH2 0x006f
00000033: JUMPI
00000034: DUP1
00000035: PUSH4 0xc80493cf
0000003a: EQ
0000003b: PUSH2 0x0667
0000003e: JUMPI
0000003f: DUP1
00000040: PUSH4 0xca15c873
00000045: EQ
00000046: PUSH2 0x0689
00000049: JUMPI
0000004a: DUP1
0000004b: PUSH4 0xd547741f
00000050: EQ
00000051: PUSH2 0x06a9
00000054: JUMPI
00000055: DUP1
00000056: PUSH4 0xe91d6390
0000005b: EQ
0000005c: PUSH2 0x06c9
0000005f: JUMPI
00000060: DUP1
00000061: PUSH4 0xff55cd40
00000066: EQ
00000067: PUSH2 0x06df
0000006a: JUMPI
0000006b: PUSH1 0x00
0000006d: DUP1
0000006e: REVERT
0000006f: JUMPDEST
00000070: DUP1
00000071: PUSH4 0xb0cba84e
00000076: EQ
00000077: PUSH2 0x05d3
0000007a: JUMPI
0000007b: DUP1
0000007c: PUSH4 0xbbc4e8c2
00000081: EQ
00000082: PUSH2 0x05f3
00000085: JUMPI
00000086: DUP1
00000087: PUSH4 0xc0c53b8b
0000008c: EQ
0000008d: PUSH2 0x0627
00000090: JUMPI
00000091: DUP1
00000092: PUSH4 0xc4d66de8
00000097: EQ
00000098: PUSH2 0x0647
0000009b: JUMPI
0000009c: PUSH1 0x00
0000009e: DUP1
0000009f: REVERT
000000a0: JUMPDEST
000000a1: DUP1
000000a2: PUSH4 0x91d14854
000000a7: GT
000000a8: PUSH2 0x00e7
000000ab: JUMPI
000000ac: DUP1
000000ad: PUSH4 0x91d14854
000000b2: EQ
000000b3: PUSH2 0x0548
000000b6: JUMPI
000000b7: DUP1
000000b8: PUSH4 0x9769b439
000000bd: EQ
000000be: PUSH2 0x0568
000000c1: JUMPI
000000c2: DUP1
000000c3: PUSH4 0x9bb2a2dd
000000c8: EQ
000000c9: PUSH2 0x0588
000000cc: JUMPI
000000cd: DUP1
000000ce: PUSH4 0xa217fddf
000000d3: EQ
000000d4: PUSH2 0x059e
000000d7: JUMPI
000000d8: DUP1
000000d9: PUSH4 0xa69cc360
000000de: EQ
000000df: PUSH2 0x05b3
000000e2: JUMPI
000000e3: PUSH1 0x00
000000e5: DUP1
000000e6: REVERT
000000e7: JUMPDEST
000000e8: DUP1
000000e9: PUSH4 0x6cfc7d64
000000ee: EQ
000000ef: PUSH2 0x0497
000000f2: JUMPI
000000f3: DUP1
000000f4: PUSH4 0x7259c116
000000f9: EQ
000000fa: PUSH2 0x04cd
000000fd: JUMPI
000000fe: DUP1
000000ff: PUSH4 0x86c051eb
00000104: EQ
00000105: PUSH2 0x04ed
00000108: JUMPI
00000109: DUP1
0000010a: PUSH4 0x9010d07c
0000010f: EQ
00000110: PUSH2 0x0528
00000113: JUMPI
00000114: PUSH1 0x00
00000116: DUP1
00000117: REVERT
00000118: JUMPDEST
00000119: DUP1
0000011a: PUSH4 0x36568abe
0000011f: GT
00000120: PUSH2 0x019b
00000123: JUMPI
00000124: DUP1
00000125: PUSH4 0x4e9e82b3
0000012a: GT
0000012b: PUSH2 0x016a
0000012e: JUMPI
0000012f: DUP1
00000130: PUSH4 0x4e9e82b3
00000135: EQ
00000136: PUSH2 0x03f7
00000139: JUMPI
0000013a: DUP1
0000013b: PUSH4 0x5573b8b6
00000140: EQ
00000141: PUSH2 0x0417
00000144: JUMPI
00000145: DUP1
00000146: PUSH4 0x5c75f49d
0000014b: EQ
0000014c: PUSH2 0x0437
0000014f: JUMPI
00000150: DUP1
00000151: PUSH4 0x5fc1eba3
00000156: EQ
00000157: PUSH2 0x0457
0000015a: JUMPI
0000015b: DUP1
0000015c: PUSH4 0x64f8ebd9
00000161: EQ
00000162: PUSH2 0x0477
00000165: JUMPI
00000166: PUSH1 0x00
00000168: DUP1
00000169: REVERT
0000016a: JUMPDEST
0000016b: DUP1
0000016c: PUSH4 0x36568abe
00000171: EQ
00000172: PUSH2 0x035f
00000175: JUMPI
00000176: DUP1
00000177: PUSH4 0x410ec2e2
0000017c: EQ
0000017d: PUSH2 0x037f
00000180: JUMPI
00000181: DUP1
00000182: PUSH4 0x468eaa29
00000187: EQ
00000188: PUSH2 0x03b7
0000018b: JUMPI
0000018c: DUP1
0000018d: PUSH4 0x485cc955
00000192: EQ
00000193: PUSH2 0x03d7
00000196: JUMPI
00000197: PUSH1 0x00
00000199: DUP1
0000019a: REVERT
0000019b: JUMPDEST
0000019c: DUP1
0000019d: PUSH4 0x23dc68d1
000001a2: GT
000001a3: PUSH2 0x01e2
000001a6: JUMPI
000001a7: DUP1
000001a8: PUSH4 0x23dc68d1
000001ad: EQ
000001ae: PUSH2 0x02ad
000001b1: JUMPI
000001b2: DUP1
000001b3: PUSH4 0x241827dc
000001b8: EQ
000001b9: PUSH2 0x02cf
000001bc: JUMPI
000001bd: DUP1
000001be: PUSH4 0x248a9ca3
000001c3: EQ
000001c4: PUSH2 0x02ef
000001c7: JUMPI
000001c8: DUP1
000001c9: PUSH4 0x2f2ff15d
000001ce: EQ
000001cf: PUSH2 0x031f
000001d2: JUMPI
000001d3: DUP1
000001d4: PUSH4 0x333271d0
000001d9: EQ
000001da: PUSH2 0x033f
000001dd: JUMPI
000001de: PUSH1 0x00
000001e0: DUP1
000001e1: REVERT
000001e2: JUMPDEST
000001e3: DUP1
000001e4: PUSH4 0x01ffc9a7
000001e9: EQ
000001ea: PUSH2 0x0214
000001ed: JUMPI
000001ee: DUP1
000001ef: PUSH4 0x096ae28c
000001f4: EQ
000001f5: PUSH2 0x0249
000001f8: JUMPI
000001f9: DUP1
000001fa: PUSH4 0x1bc29a76
000001ff: EQ
00000200: PUSH2 0x026d
00000203: JUMPI
00000204: DUP1
00000205: PUSH4 0x1dd7cecf
0000020a: EQ
0000020b: PUSH2 0x028d
0000020e: JUMPI
0000020f: JUMPDEST
00000210: PUSH1 0x00
00000212: DUP1
00000213: REVERT
00000214: JUMPDEST
00000215: CALLVALUE
00000216: DUP1
00000217: ISZERO
00000218: PUSH2 0x0220
0000021b: JUMPI
0000021c: PUSH1 0x00
0000021e: DUP1
0000021f: REVERT
00000220: JUMPDEST
00000221: POP
00000222: PUSH2 0x0234
00000225: PUSH2 0x022f
00000228: CALLDATASIZE
00000229: PUSH1 0x04
0000022b: PUSH2 0x23e0
0000022e: JUMP
0000022f: JUMPDEST
00000230: PUSH2 0x06f2
00000233: JUMP
00000234: JUMPDEST
00000235: PUSH1 0x40
00000237: MLOAD
00000238: SWAP1
00000239: ISZERO
0000023a: ISZERO
0000023b: DUP2
0000023c: MSTORE
0000023d: PUSH1 0x20
0000023f: ADD
00000240: JUMPDEST
00000241: PUSH1 0x40
00000243: MLOAD
00000244: DUP1
00000245: SWAP2
00000246: SUB
00000247: SWAP1
00000248: RETURN
00000249: JUMPDEST
0000024a: CALLVALUE
0000024b: DUP1
0000024c: ISZERO
0000024d: PUSH2 0x0255
00000250: JUMPI
00000251: PUSH1 0x00
00000253: DUP1
00000254: REVERT
00000255: JUMPDEST
00000256: POP
00000257: PUSH2 0x025f
0000025a: PUSH1 0xd0
0000025c: SLOAD
0000025d: DUP2
0000025e: JUMP
0000025f: JUMPDEST
00000260: PUSH1 0x40
00000262: MLOAD
00000263: SWAP1
00000264: DUP2
00000265: MSTORE
00000266: PUSH1 0x20
00000268: ADD
00000269: PUSH2 0x0240
0000026c: JUMP
0000026d: JUMPDEST
0000026e: CALLVALUE
0000026f: DUP1
00000270: ISZERO
00000271: PUSH2 0x0279
00000274: JUMPI
00000275: PUSH1 0x00
00000277: DUP1
00000278: REVERT
00000279: JUMPDEST
0000027a: POP
0000027b: PUSH2 0x0234
0000027e: PUSH2 0x0288
00000281: CALLDATASIZE
00000282: PUSH1 0x04
00000284: PUSH2 0x241f
00000287: JUMP
00000288: JUMPDEST
00000289: PUSH2 0x071d
0000028c: JUMP
0000028d: JUMPDEST
0000028e: CALLVALUE
0000028f: DUP1
00000290: ISZERO
00000291: PUSH2 0x0299
00000294: JUMPI
00000295: PUSH1 0x00
00000297: DUP1
00000298: REVERT
00000299: JUMPDEST
0000029a: POP
0000029b: PUSH2 0x025f
0000029e: PUSH2 0x02a8
000002a1: CALLDATASIZE
000002a2: PUSH1 0x04
000002a4: PUSH2 0x24a0
000002a7: JUMP
000002a8: JUMPDEST
000002a9: PUSH2 0x0886
000002ac: JUMP
000002ad: JUMPDEST
000002ae: CALLVALUE
000002af: DUP1
000002b0: ISZERO
000002b1: PUSH2 0x02b9
000002b4: JUMPI
000002b5: PUSH1 0x00
000002b7: DUP1
000002b8: REVERT
000002b9: JUMPDEST
000002ba: POP
000002bb: PUSH2 0x02cd
000002be: PUSH2 0x02c8
000002c1: CALLDATASIZE
000002c2: PUSH1 0x04
000002c4: PUSH2 0x24f5
000002c7: JUMP
000002c8: JUMPDEST
000002c9: PUSH2 0x08f5
000002cc: JUMP
000002cd: JUMPDEST
000002ce: STOP
000002cf: JUMPDEST
000002d0: CALLVALUE
000002d1: DUP1
000002d2: ISZERO
000002d3: PUSH2 0x02db
000002d6: JUMPI
000002d7: PUSH1 0x00
000002d9: DUP1
000002da: REVERT
000002db: JUMPDEST
000002dc: POP
000002dd: PUSH2 0x0234
000002e0: PUSH2 0x02ea
000002e3: CALLDATASIZE
000002e4: PUSH1 0x04
000002e6: PUSH2 0x254c
000002e9: JUMP
000002ea: JUMPDEST
000002eb: PUSH2 0x0aa8
000002ee: JUMP
000002ef: JUMPDEST
000002f0: CALLVALUE
000002f1: DUP1
000002f2: ISZERO
000002f3: PUSH2 0x02fb
000002f6: JUMPI
000002f7: PUSH1 0x00
000002f9: DUP1
000002fa: REVERT
000002fb: JUMPDEST
000002fc: POP
000002fd: PUSH2 0x025f
00000300: PUSH2 0x030a
00000303: CALLDATASIZE
00000304: PUSH1 0x04
00000306: PUSH2 0x257c
00000309: JUMP
0000030a: JUMPDEST
0000030b: PUSH1 0x00
0000030d: SWAP1
0000030e: DUP2
0000030f: MSTORE
00000310: PUSH1 0x65
00000312: PUSH1 0x20
00000314: MSTORE
00000315: PUSH1 0x40
00000317: SWAP1
00000318: KECCAK256
00000319: PUSH1 0x01
0000031b: ADD
0000031c: SLOAD
0000031d: SWAP1
0000031e: JUMP
0000031f: JUMPDEST
00000320: CALLVALUE
00000321: DUP1
00000322: ISZERO
00000323: PUSH2 0x032b
00000326: JUMPI
00000327: PUSH1 0x00
00000329: DUP1
0000032a: REVERT
0000032b: JUMPDEST
0000032c: POP
0000032d: PUSH2 0x02cd
00000330: PUSH2 0x033a
00000333: CALLDATASIZE
00000334: PUSH1 0x04
00000336: PUSH2 0x254c
00000339: JUMP
0000033a: JUMPDEST
0000033b: PUSH2 0x0ae9
0000033e: JUMP
0000033f: JUMPDEST
00000340: CALLVALUE
00000341: DUP1
00000342: ISZERO
00000343: PUSH2 0x034b
00000346: JUMPI
00000347: PUSH1 0x00
00000349: DUP1
0000034a: REVERT
0000034b: JUMPDEST
0000034c: POP
0000034d: PUSH2 0x02cd
00000350: PUSH2 0x035a
00000353: CALLDATASIZE
00000354: PUSH1 0x04
00000356: PUSH2 0x2595
00000359: JUMP
0000035a: JUMPDEST
0000035b: PUSH2 0x0b13
0000035e: JUMP
0000035f: JUMPDEST
00000360: CALLVALUE
00000361: DUP1
00000362: ISZERO
00000363: PUSH2 0x036b
00000366: JUMPI
00000367: PUSH1 0x00
00000369: DUP1
0000036a: REVERT
0000036b: JUMPDEST
0000036c: POP
0000036d: PUSH2 0x02cd
00000370: PUSH2 0x037a
00000373: CALLDATASIZE
00000374: PUSH1 0x04
00000376: PUSH2 0x254c
00000379: JUMP
0000037a: JUMPDEST
0000037b: PUSH2 0x0c24
0000037e: JUMP
0000037f: JUMPDEST
00000380: CALLVALUE
00000381: DUP1
00000382: ISZERO
00000383: PUSH2 0x038b
00000386: JUMPI
00000387: PUSH1 0x00
00000389: DUP1
0000038a: REVERT
0000038b: JUMPDEST
0000038c: POP
0000038d: PUSH1 0xc9
0000038f: SLOAD
00000390: PUSH2 0x039f
00000393: SWAP1
00000394: PUSH1 0x01
00000396: PUSH1 0x01
00000398: PUSH1 0xa0
0000039a: SHL
0000039b: SUB
0000039c: AND
0000039d: DUP2
0000039e: JUMP
0000039f: JUMPDEST
000003a0: PUSH1 0x40
000003a2: MLOAD
000003a3: PUSH1 0x01
000003a5: PUSH1 0x01
000003a7: PUSH1 0xa0
000003a9: SHL
000003aa: SUB
000003ab: SWAP1
000003ac: SWAP2
000003ad: AND
000003ae: DUP2
000003af: MSTORE
000003b0: PUSH1 0x20
000003b2: ADD
000003b3: PUSH2 0x0240
000003b6: JUMP
000003b7: JUMPDEST
000003b8: CALLVALUE
000003b9: DUP1
000003ba: ISZERO
000003bb: PUSH2 0x03c3
000003be: JUMPI
000003bf: PUSH1 0x00
000003c1: DUP1
000003c2: REVERT
000003c3: JUMPDEST
000003c4: POP
000003c5: PUSH2 0x0234
000003c8: PUSH2 0x03d2
000003cb: CALLDATASIZE
000003cc: PUSH1 0x04
000003ce: PUSH2 0x25b7
000003d1: JUMP
000003d2: JUMPDEST
000003d3: PUSH2 0x0ca2
000003d6: JUMP
000003d7: JUMPDEST
000003d8: CALLVALUE
000003d9: DUP1
000003da: ISZERO
000003db: PUSH2 0x03e3
000003de: JUMPI
000003df: PUSH1 0x00
000003e1: DUP1
000003e2: REVERT
000003e3: JUMPDEST
000003e4: POP
000003e5: PUSH2 0x02cd
000003e8: PUSH2 0x03f2
000003eb: CALLDATASIZE
000003ec: PUSH1 0x04
000003ee: PUSH2 0x25e3
000003f1: JUMP
000003f2: JUMPDEST
000003f3: PUSH2 0x0db1
000003f6: JUMP
000003f7: JUMPDEST
000003f8: CALLVALUE
000003f9: DUP1
000003fa: ISZERO
000003fb: PUSH2 0x0403
000003fe: JUMPI
000003ff: PUSH1 0x00
00000401: DUP1
00000402: REVERT
00000403: JUMPDEST
00000404: POP
00000405: PUSH2 0x025f
00000408: PUSH2 0x0412
0000040b: CALLDATASIZE
0000040c: PUSH1 0x04
0000040e: PUSH2 0x2611
00000411: JUMP
00000412: JUMPDEST
00000413: PUSH2 0x0e98
00000416: JUMP
00000417: JUMPDEST
00000418: CALLVALUE
00000419: DUP1
0000041a: ISZERO
0000041b: PUSH2 0x0423
0000041e: JUMPI
0000041f: PUSH1 0x00
00000421: DUP1
00000422: REVERT
00000423: JUMPDEST
00000424: POP
00000425: PUSH1 0xca
00000427: SLOAD
00000428: PUSH2 0x039f
0000042b: SWAP1
0000042c: PUSH1 0x01
0000042e: PUSH1 0x01
00000430: PUSH1 0xa0
00000432: SHL
00000433: SUB
00000434: AND
00000435: DUP2
00000436: JUMP
00000437: JUMPDEST
00000438: CALLVALUE
00000439: DUP1
0000043a: ISZERO
0000043b: PUSH2 0x0443
0000043e: JUMPI
0000043f: PUSH1 0x00
00000441: DUP1
00000442: REVERT
00000443: JUMPDEST
00000444: POP
00000445: PUSH2 0x02cd
00000448: PUSH2 0x0452
0000044b: CALLDATASIZE
0000044c: PUSH1 0x04
0000044e: PUSH2 0x2659
00000451: JUMP
00000452: JUMPDEST
00000453: PUSH2 0x111a
00000456: JUMP
00000457: JUMPDEST
00000458: CALLVALUE
00000459: DUP1
0000045a: ISZERO
0000045b: PUSH2 0x0463
0000045e: JUMPI
0000045f: PUSH1 0x00
00000461: DUP1
00000462: REVERT
00000463: JUMPDEST
00000464: POP
00000465: PUSH2 0x02cd
00000468: PUSH2 0x0472
0000046b: CALLDATASIZE
0000046c: PUSH1 0x04
0000046e: PUSH2 0x257c
00000471: JUMP
00000472: JUMPDEST
00000473: PUSH2 0x1246
00000476: JUMP
00000477: JUMPDEST
00000478: CALLVALUE
00000479: DUP1
0000047a: ISZERO
0000047b: PUSH2 0x0483
0000047e: JUMPI
0000047f: PUSH1 0x00
00000481: DUP1
00000482: REVERT
00000483: JUMPDEST
00000484: POP
00000485: PUSH2 0x025f
00000488: PUSH2 0x0492
0000048b: CALLDATASIZE
0000048c: PUSH1 0x04
0000048e: PUSH2 0x254c
00000491: JUMP
00000492: JUMPDEST
00000493: PUSH2 0x12fd
00000496: JUMP
00000497: JUMPDEST
00000498: CALLVALUE
00000499: DUP1
0000049a: ISZERO
0000049b: PUSH2 0x04a3
0000049e: JUMPI
0000049f: PUSH1 0x00
000004a1: DUP1
000004a2: REVERT
000004a3: JUMPDEST
000004a4: POP
000004a5: PUSH2 0x039f
000004a8: PUSH2 0x04b2
000004ab: CALLDATASIZE
000004ac: PUSH1 0x04
000004ae: PUSH2 0x257c
000004b1: JUMP
000004b2: JUMPDEST
000004b3: PUSH1 0xcb
000004b5: PUSH1 0x20
000004b7: MSTORE
000004b8: PUSH1 0x00
000004ba: SWAP1
000004bb: DUP2
000004bc: MSTORE
000004bd: PUSH1 0x40
000004bf: SWAP1
000004c0: KECCAK256
000004c1: SLOAD
000004c2: PUSH1 0x01
000004c4: PUSH1 0x01
000004c6: PUSH1 0xa0
000004c8: SHL
000004c9: SUB
000004ca: AND
000004cb: DUP2
000004cc: JUMP
000004cd: JUMPDEST
000004ce: CALLVALUE
000004cf: DUP1
000004d0: ISZERO
000004d1: PUSH2 0x04d9
000004d4: JUMPI
000004d5: PUSH1 0x00
000004d7: DUP1
000004d8: REVERT
000004d9: JUMPDEST
000004da: POP
000004db: PUSH2 0x039f
000004de: PUSH2 0x04e8
000004e1: CALLDATASIZE
000004e2: PUSH1 0x04
000004e4: PUSH2 0x257c
000004e7: JUMP
000004e8: JUMPDEST
000004e9: PUSH2 0x13b5
000004ec: JUMP
000004ed: JUMPDEST
000004ee: CALLVALUE
000004ef: DUP1
000004f0: ISZERO
000004f1: PUSH2 0x04f9
000004f4: JUMPI
000004f5: PUSH1 0x00
000004f7: DUP1
000004f8: REVERT
000004f9: JUMPDEST
000004fa: POP
000004fb: PUSH2 0x0234
000004fe: PUSH2 0x0508
00000501: CALLDATASIZE
00000502: PUSH1 0x04
00000504: PUSH2 0x25b7
00000507: JUMP
00000508: JUMPDEST
00000509: PUSH1 0xcd
0000050b: PUSH1 0x20
0000050d: SWAP1
0000050e: DUP2
0000050f: MSTORE
00000510: PUSH1 0x00
00000512: SWAP3
00000513: DUP4
00000514: MSTORE
00000515: PUSH1 0x40
00000517: DUP1
00000518: DUP5
00000519: KECCAK256
0000051a: SWAP1
0000051b: SWAP2
0000051c: MSTORE
0000051d: SWAP1
0000051e: DUP3
0000051f: MSTORE
00000520: SWAP1
00000521: KECCAK256
00000522: SLOAD
00000523: PUSH1 0xff
00000525: AND
00000526: DUP2
00000527: JUMP
00000528: JUMPDEST
00000529: CALLVALUE
0000052a: DUP1
0000052b: ISZERO
0000052c: PUSH2 0x0534
0000052f: JUMPI
00000530: PUSH1 0x00
00000532: DUP1
00000533: REVERT
00000534: JUMPDEST
00000535: POP
00000536: PUSH2 0x039f
00000539: PUSH2 0x0543
0000053c: CALLDATASIZE
0000053d: PUSH1 0x04
0000053f: PUSH2 0x2595
00000542: JUMP
00000543: JUMPDEST
00000544: PUSH2 0x1441
00000547: JUMP
00000548: JUMPDEST
00000549: CALLVALUE
0000054a: DUP1
0000054b: ISZERO
0000054c: PUSH2 0x0554
0000054f: JUMPI
00000550: PUSH1 0x00
00000552: DUP1
00000553: REVERT
00000554: JUMPDEST
00000555: POP
00000556: PUSH2 0x0234
00000559: PUSH2 0x0563
0000055c: CALLDATASIZE
0000055d: PUSH1 0x04
0000055f: PUSH2 0x254c
00000562: JUMP
00000563: JUMPDEST
00000564: PUSH2 0x1459
00000567: JUMP
00000568: JUMPDEST
00000569: CALLVALUE
0000056a: DUP1
0000056b: ISZERO
0000056c: PUSH2 0x0574
0000056f: JUMPI
00000570: PUSH1 0x00
00000572: DUP1
00000573: REVERT
00000574: JUMPDEST
00000575: POP
00000576: PUSH2 0x02cd
00000579: PUSH2 0x0583
0000057c: CALLDATASIZE
0000057d: PUSH1 0x04
0000057f: PUSH2 0x269b
00000582: JUMP
00000583: JUMPDEST
00000584: PUSH2 0x1484
00000587: JUMP
00000588: JUMPDEST
00000589: CALLVALUE
0000058a: DUP1
0000058b: ISZERO
0000058c: PUSH2 0x0594
0000058f: JUMPI
00000590: PUSH1 0x00
00000592: DUP1
00000593: REVERT
00000594: JUMPDEST
00000595: POP
00000596: PUSH2 0x025f
00000599: PUSH1 0xce
0000059b: SLOAD
0000059c: DUP2
0000059d: JUMP
0000059e: JUMPDEST
0000059f: CALLVALUE
000005a0: DUP1
000005a1: ISZERO
000005a2: PUSH2 0x05aa
000005a5: JUMPI
000005a6: PUSH1 0x00
000005a8: DUP1
000005a9: REVERT
000005aa: JUMPDEST
000005ab: POP
000005ac: PUSH2 0x025f
000005af: PUSH1 0x00
000005b1: DUP2
000005b2: JUMP
000005b3: JUMPDEST
000005b4: CALLVALUE
000005b5: DUP1
000005b6: ISZERO
000005b7: PUSH2 0x05bf
000005ba: JUMPI
000005bb: PUSH1 0x00
000005bd: DUP1
000005be: REVERT
000005bf: JUMPDEST
000005c0: POP
000005c1: PUSH2 0x0234
000005c4: PUSH2 0x05ce
000005c7: CALLDATASIZE
000005c8: PUSH1 0x04
000005ca: PUSH2 0x254c
000005cd: JUMP
000005ce: JUMPDEST
000005cf: PUSH2 0x1707
000005d2: JUMP
000005d3: JUMPDEST
000005d4: CALLVALUE
000005d5: DUP1
000005d6: ISZERO
000005d7: PUSH2 0x05df
000005da: JUMPI
000005db: PUSH1 0x00
000005dd: DUP1
000005de: REVERT
000005df: JUMPDEST
000005e0: POP
000005e1: PUSH2 0x0234
000005e4: PUSH2 0x05ee
000005e7: CALLDATASIZE
000005e8: PUSH1 0x04
000005ea: PUSH2 0x2659
000005ed: JUMP
000005ee: JUMPDEST
000005ef: PUSH2 0x17d1
000005f2: JUMP
000005f3: JUMPDEST
000005f4: CALLVALUE
000005f5: DUP1
000005f6: ISZERO
000005f7: PUSH2 0x05ff
000005fa: JUMPI
000005fb: PUSH1 0x00
000005fd: DUP1
000005fe: REVERT
000005ff: JUMPDEST
00000600: POP
00000601: PUSH2 0x025f
00000604: PUSH32 0x96e3fc3be15159903e053027cff8a23f39a990e0194abcd8ac1cf1b355b8b93c
00000625: DUP2
00000626: JUMP
00000627: JUMPDEST
00000628: CALLVALUE
00000629: DUP1
0000062a: ISZERO
0000062b: PUSH2 0x0633
0000062e: JUMPI
0000062f: PUSH1 0x00
00000631: DUP1
00000632: REVERT
00000633: JUMPDEST
00000634: POP
00000635: PUSH2 0x02cd
00000638: PUSH2 0x0642
0000063b: CALLDATASIZE
0000063c: PUSH1 0x04
0000063e: PUSH2 0x26e7
00000641: JUMP
00000642: JUMPDEST
00000643: PUSH2 0x1843
00000646: JUMP
00000647: JUMPDEST
00000648: CALLVALUE
00000649: DUP1
0000064a: ISZERO
0000064b: PUSH2 0x0653
0000064e: JUMPI
0000064f: PUSH1 0x00
00000651: DUP1
00000652: REVERT
00000653: JUMPDEST
00000654: POP
00000655: PUSH2 0x02cd
00000658: PUSH2 0x0662
0000065b: CALLDATASIZE
0000065c: PUSH1 0x04
0000065e: PUSH2 0x2727
00000661: JUMP
00000662: JUMPDEST
00000663: PUSH2 0x193a
00000666: JUMP
00000667: JUMPDEST
00000668: CALLVALUE
00000669: DUP1
0000066a: ISZERO
0000066b: PUSH2 0x0673
0000066e: JUMPI
0000066f: PUSH1 0x00
00000671: DUP1
00000672: REVERT
00000673: JUMPDEST
00000674: POP
00000675: PUSH2 0x025f
00000678: PUSH1 0x00
0000067a: DUP1
0000067b: MLOAD
0000067c: PUSH1 0x20
0000067e: PUSH2 0x2a15
00000681: DUP4
00000682: CODECOPY
00000683: DUP2
00000684: MLOAD
00000685: SWAP2
00000686: MSTORE
00000687: DUP2
00000688: JUMP
00000689: JUMPDEST
0000068a: CALLVALUE
0000068b: DUP1
0000068c: ISZERO
0000068d: PUSH2 0x0695
00000690: JUMPI
00000691: PUSH1 0x00
00000693: DUP1
00000694: REVERT
00000695: JUMPDEST
00000696: POP
00000697: PUSH2 0x025f
0000069a: PUSH2 0x06a4
0000069d: CALLDATASIZE
0000069e: PUSH1 0x04
000006a0: PUSH2 0x257c
000006a3: JUMP
000006a4: JUMPDEST
000006a5: PUSH2 0x1a2a
000006a8: JUMP
000006a9: JUMPDEST
000006aa: CALLVALUE
000006ab: DUP1
000006ac: ISZERO
000006ad: PUSH2 0x06b5
000006b0: JUMPI
000006b1: PUSH1 0x00
000006b3: DUP1
000006b4: REVERT
000006b5: JUMPDEST
000006b6: POP
000006b7: PUSH2 0x02cd
000006ba: PUSH2 0x06c4
000006bd: CALLDATASIZE
000006be: PUSH1 0x04
000006c0: PUSH2 0x254c
000006c3: JUMP
000006c4: JUMPDEST
000006c5: PUSH2 0x1a41
000006c8: JUMP
000006c9: JUMPDEST
000006ca: CALLVALUE
000006cb: DUP1
000006cc: ISZERO
000006cd: PUSH2 0x06d5
000006d0: JUMPI
000006d1: PUSH1 0x00
000006d3: DUP1
000006d4: REVERT
000006d5: JUMPDEST
000006d6: POP
000006d7: PUSH2 0x025f
000006da: PUSH1 0xcf
000006dc: SLOAD
000006dd: DUP2
000006de: JUMP
000006df: JUMPDEST
000006e0: PUSH2 0x02cd
000006e3: PUSH2 0x06ed
000006e6: CALLDATASIZE
000006e7: PUSH1 0x04
000006e9: PUSH2 0x24f5
000006ec: JUMP
000006ed: JUMPDEST
000006ee: PUSH2 0x1a66
000006f1: JUMP
000006f2: JUMPDEST
000006f3: PUSH1 0x00
000006f5: PUSH1 0x01
000006f7: PUSH1 0x01
000006f9: PUSH1 0xe0
000006fb: SHL
000006fc: SUB
000006fd: NOT
000006fe: DUP3
000006ff: AND
00000700: PUSH4 0x5a05180f
00000705: PUSH1 0xe0
00000707: SHL
00000708: EQ
00000709: DUP1
0000070a: PUSH2 0x0717
0000070d: JUMPI
0000070e: POP
0000070f: PUSH2 0x0717
00000712: DUP3
00000713: PUSH2 0x1c10
00000716: JUMP
00000717: JUMPDEST
00000718: SWAP3
00000719: SWAP2
0000071a: POP
0000071b: POP
0000071c: JUMP
0000071d: JUMPDEST
0000071e: PUSH1 0xca
00000720: SLOAD
00000721: PUSH1 0x00
00000723: SWAP1
00000724: PUSH1 0x01
00000726: PUSH1 0x01
00000728: PUSH1 0xa0
0000072a: SHL
0000072b: SUB
0000072c: AND
0000072d: CALLER
0000072e: EQ
0000072f: PUSH2 0x077f
00000732: JUMPI
00000733: PUSH1 0x40
00000735: MLOAD
00000736: PUSH3 0x461bcd
0000073a: PUSH1 0xe5
0000073c: SHL
0000073d: DUP2
0000073e: MSTORE
0000073f: PUSH1 0x20
00000741: PUSH1 0x04
00000743: DUP3
00000744: ADD
00000745: MSTORE
00000746: PUSH1 0x1c
00000748: PUSH1 0x24
0000074a: DUP3
0000074b: ADD
0000074c: MSTORE
0000074d: PUSH32 0x53656e646572206973206e6f742061204d65737361676550726f787900000000
0000076e: PUSH1 0x44
00000770: DUP3
00000771: ADD
00000772: MSTORE
00000773: PUSH1 0x64
00000775: ADD
00000776: JUMPDEST
00000777: PUSH1 0x40
00000779: MLOAD
0000077a: DUP1
0000077b: SWAP2
0000077c: SUB
0000077d: SWAP1
0000077e: REVERT
0000077f: JUMPDEST
00000780: DUP2
00000781: ISZERO
00000782: PUSH2 0x087c
00000785: JUMPI
00000786: PUSH1 0xc9
00000788: SLOAD
00000789: PUSH1 0x40
0000078b: MLOAD
0000078c: PUSH4 0x35817773
00000791: PUSH1 0xe0
00000793: SHL
00000794: DUP2
00000795: MSTORE
00000796: PUSH1 0x20
00000798: PUSH1 0x04
0000079a: DUP3
0000079b: ADD
0000079c: MSTORE
0000079d: PUSH1 0x07
0000079f: PUSH1 0x24
000007a1: DUP3
000007a2: ADD
000007a3: MSTORE
000007a4: PUSH7 0x57616c6c657473
000007ac: PUSH1 0xc8
000007ae: SHL
000007af: PUSH1 0x44
000007b1: DUP3
000007b2: ADD
000007b3: MSTORE
000007b4: PUSH1 0x01
000007b6: PUSH1 0x01
000007b8: PUSH1 0xa0
000007ba: SHL
000007bb: SUB
000007bc: SWAP1
000007bd: SWAP2
000007be: AND
000007bf: SWAP1
000007c0: PUSH4 0x35817773
000007c5: SWAP1
000007c6: PUSH1 0x64
000007c8: ADD
000007c9: PUSH1 0x20
000007cb: PUSH1 0x40
000007cd: MLOAD
000007ce: DUP1
000007cf: DUP4
000007d0: SUB
000007d1: DUP2
000007d2: DUP7
000007d3: GAS
000007d4: STATICCALL
000007d5: ISZERO
000007d6: DUP1
000007d7: ISZERO
000007d8: PUSH2 0x07e5
000007db: JUMPI
000007dc: RETURNDATASIZE
000007dd: PUSH1 0x00
000007df: DUP1
000007e0: RETURNDATACOPY
000007e1: RETURNDATASIZE
000007e2: PUSH1 0x00
000007e4: REVERT
000007e5: JUMPDEST
000007e6: POP
000007e7: POP
000007e8: POP
000007e9: POP
000007ea: PUSH1 0x40
000007ec: MLOAD
000007ed: RETURNDATASIZE
000007ee: PUSH1 0x1f
000007f0: NOT
000007f1: PUSH1 0x1f
000007f3: DUP3
000007f4: ADD
000007f5: AND
000007f6: DUP3
000007f7: ADD
000007f8: DUP1
000007f9: PUSH1 0x40
000007fb: MSTORE
000007fc: POP
000007fd: DUP2
000007fe: ADD
000007ff: SWAP1
00000800: PUSH2 0x0809
00000803: SWAP2
00000804: SWAP1
00000805: PUSH2 0x2744
00000808: JUMP
00000809: JUMPDEST
0000080a: PUSH1 0x40
0000080c: MLOAD
0000080d: PUSH4 0x37e9add9
00000812: PUSH1 0xe0
00000814: SHL
00000815: DUP2
00000816: MSTORE
00000817: PUSH1 0x04
00000819: DUP2
0000081a: ADD
0000081b: DUP7
0000081c: SWAP1
0000081d: MSTORE
0000081e: PUSH1 0x01
00000820: PUSH1 0x01
00000822: PUSH1 0xa0
00000824: SHL
00000825: SUB
00000826: DUP6
00000827: DUP2
00000828: AND
00000829: PUSH1 0x24
0000082b: DUP4
0000082c: ADD
0000082d: MSTORE
0000082e: PUSH1 0x44
00000830: DUP3
00000831: ADD
00000832: DUP6
00000833: SWAP1
00000834: MSTORE
00000835: PUSH1 0x00
00000837: PUSH1 0x64
00000839: DUP4
0000083a: ADD
0000083b: MSTORE
0000083c: SWAP2
0000083d: SWAP1
0000083e: SWAP2
0000083f: AND
00000840: SWAP1
00000841: PUSH4 0x37e9add9
00000846: SWAP1
00000847: PUSH1 0x84
00000849: ADD
0000084a: PUSH1 0x00
0000084c: PUSH1 0x40
0000084e: MLOAD
0000084f: DUP1
00000850: DUP4
00000851: SUB
00000852: DUP2
00000853: PUSH1 0x00
00000855: DUP8
00000856: DUP1
00000857: EXTCODESIZE
00000858: ISZERO
00000859: DUP1
0000085a: ISZERO
0000085b: PUSH2 0x0863
0000085e: JUMPI
0000085f: PUSH1 0x00
00000861: DUP1
00000862: REVERT
00000863: JUMPDEST
00000864: POP
00000865: GAS
00000866: CALL
00000867: ISZERO
00000868: DUP1
00000869: ISZERO
0000086a: PUSH2 0x0877
0000086d: JUMPI
0000086e: RETURNDATASIZE
0000086f: PUSH1 0x00
00000871: DUP1
00000872: RETURNDATACOPY
00000873: RETURNDATASIZE
00000874: PUSH1 0x00
00000876: REVERT
00000877: JUMPDEST
00000878: POP
00000879: POP
0000087a: POP
0000087b: POP
0000087c: JUMPDEST
0000087d: POP
0000087e: PUSH1 0x01
00000880: SWAP4
00000881: SWAP3
00000882: POP
00000883: POP
00000884: POP
00000885: JUMP
00000886: JUMPDEST
00000887: PUSH1 0x01
00000889: PUSH1 0x01
0000088b: PUSH1 0xa0
0000088d: SHL
0000088e: SUB
0000088f: DUP4
00000890: AND
00000891: PUSH1 0x00
00000893: SWAP1
00000894: DUP2
00000895: MSTORE
00000896: PUSH1 0xcc
00000898: PUSH1 0x20
0000089a: SWAP1
0000089b: DUP2
0000089c: MSTORE
0000089d: PUSH1 0x40
0000089f: DUP1
000008a0: DUP4
000008a1: KECCAK256
000008a2: DUP2
000008a3: MLOAD
000008a4: PUSH1 0x1f
000008a6: DUP7
000008a7: ADD
000008a8: DUP5
000008a9: SWAP1
000008aa: DIV
000008ab: DUP5
000008ac: MUL
000008ad: DUP2
000008ae: ADD
000008af: DUP5
000008b0: ADD
000008b1: SWAP1
000008b2: SWAP3
000008b3: MSTORE
000008b4: DUP5
000008b5: DUP3
000008b6: MSTORE
000008b7: SWAP2
000008b8: DUP4
000008b9: SWAP2
000008ba: PUSH2 0x08dd
000008bd: SWAP2
000008be: DUP8
000008bf: SWAP1
000008c0: DUP8
000008c1: SWAP1
000008c2: DUP2
000008c3: SWAP1
000008c4: DUP5
000008c5: ADD
000008c6: DUP4
000008c7: DUP3
000008c8: DUP1
000008c9: DUP3
000008ca: DUP5
000008cb: CALLDATACOPY
000008cc: PUSH1 0x00
000008ce: SWAP3
000008cf: ADD
000008d0: SWAP2
000008d1: SWAP1
000008d2: SWAP2
000008d3: MSTORE
000008d4: POP
000008d5: PUSH2 0x1c45
000008d8: SWAP3
000008d9: POP
000008da: POP
000008db: POP
000008dc: JUMP
000008dd: JUMPDEST
000008de: DUP2
000008df: MSTORE
000008e0: PUSH1 0x20
000008e2: ADD
000008e3: SWAP1
000008e4: DUP2
000008e5: MSTORE
000008e6: PUSH1 0x20
000008e8: ADD
000008e9: PUSH1 0x00
000008eb: KECCAK256
000008ec: SLOAD
000008ed: SWAP1
000008ee: POP
000008ef: SWAP4
000008f0: SWAP3
000008f1: POP
000008f2: POP
000008f3: POP
000008f4: JUMP
000008f5: JUMPDEST
000008f6: PUSH1 0x00
000008f8: PUSH2 0x0936
000008fb: DUP5
000008fc: DUP5
000008fd: DUP1
000008fe: DUP1
000008ff: PUSH1 0x1f
00000901: ADD
00000902: PUSH1 0x20
00000904: DUP1
00000905: SWAP2
00000906: DIV
00000907: MUL
00000908: PUSH1 0x20
0000090a: ADD
0000090b: PUSH1 0x40
0000090d: MLOAD
0000090e: SWAP1
0000090f: DUP2
00000910: ADD
00000911: PUSH1 0x40
00000913: MSTORE
00000914: DUP1
00000915: SWAP4
00000916: SWAP3
00000917: SWAP2
00000918: SWAP1
00000919: DUP2
0000091a: DUP2
0000091b: MSTORE
0000091c: PUSH1 0x20
0000091e: ADD
0000091f: DUP4
00000920: DUP4
00000921: DUP1
00000922: DUP3
00000923: DUP5
00000924: CALLDATACOPY
00000925: PUSH1 0x00
00000927: SWAP3
00000928: ADD
00000929: SWAP2
0000092a: SWAP1
0000092b: SWAP2
0000092c: MSTORE
0000092d: POP
0000092e: PUSH2 0x1c45
00000931: SWAP3
00000932: POP
00000933: POP
00000934: POP
00000935: JUMP
00000936: JUMPDEST
00000937: SWAP1
00000938: POP
00000939: PUSH2 0x0950
0000093c: PUSH1 0x00
0000093e: DUP1
0000093f: MLOAD
00000940: PUSH1 0x20
00000942: PUSH2 0x2a15
00000945: DUP4
00000946: CODECOPY
00000947: DUP2
00000948: MLOAD
00000949: SWAP2
0000094a: MSTORE
0000094b: CALLER
0000094c: PUSH2 0x1459
0000094f: JUMP
00000950: JUMPDEST
00000951: DUP1
00000952: PUSH2 0x0960
00000955: JUMPI
00000956: POP
00000957: PUSH2 0x0960
0000095a: CALLER
0000095b: DUP3
0000095c: PUSH2 0x0ca2
0000095f: JUMP
00000960: JUMPDEST
00000961: PUSH2 0x09a4
00000964: JUMPI
00000965: PUSH1 0x40
00000967: MLOAD
00000968: PUSH3 0x461bcd
0000096c: PUSH1 0xe5
0000096e: SHL
0000096f: DUP2
00000970: MSTORE
00000971: PUSH1 0x20
00000973: PUSH1 0x04
00000975: DUP3
00000976: ADD
00000977: MSTORE
00000978: PUSH1 0x15
0000097a: PUSH1 0x24
0000097c: DUP3
0000097d: ADD
0000097e: MSTORE
0000097f: PUSH21 0x2737ba1030baba3437b934bd32b21031b0b63632b9
00000995: PUSH1 0x59
00000997: SHL
00000998: PUSH1 0x44
0000099a: DUP3
0000099b: ADD
0000099c: MSTORE
0000099d: PUSH1 0x64
0000099f: ADD
000009a0: PUSH2 0x0776
000009a3: JUMP
000009a4: JUMPDEST
000009a5: PUSH1 0x00
000009a7: DUP2
000009a8: DUP2
000009a9: MSTORE
000009aa: PUSH1 0xcb
000009ac: PUSH1 0x20
000009ae: MSTORE
000009af: PUSH1 0x40
000009b1: SWAP1
000009b2: KECCAK256
000009b3: SLOAD
000009b4: PUSH1 0x01
000009b6: PUSH1 0x01
000009b8: PUSH1 0xa0
000009ba: SHL
000009bb: SUB
000009bc: AND
000009bd: ISZERO
000009be: PUSH2 0x0a09
000009c1: JUMPI
000009c2: PUSH1 0x40
000009c4: MLOAD
000009c5: PUSH3 0x461bcd
000009c9: PUSH1 0xe5
000009cb: SHL
000009cc: DUP2
000009cd: MSTORE
000009ce: PUSH1 0x20
000009d0: PUSH1 0x04
000009d2: DUP3
000009d3: ADD
000009d4: MSTORE
000009d5: PUSH1 0x1a
000009d7: PUSH1 0x24
000009d9: DUP3
000009da: ADD
000009db: MSTORE
000009dc: PUSH32 0x534b414c4520636861696e20697320616c726561647920736574000000000000
000009fd: PUSH1 0x44
000009ff: DUP3
00000a00: ADD
00000a01: MSTORE
00000a02: PUSH1 0x64
00000a04: ADD
00000a05: PUSH2 0x0776
00000a08: JUMP
00000a09: JUMPDEST
00000a0a: PUSH1 0x01
00000a0c: PUSH1 0x01
00000a0e: PUSH1 0xa0
00000a10: SHL
00000a11: SUB
00000a12: DUP3
00000a13: AND
00000a14: PUSH2 0x0a78
00000a17: JUMPI
00000a18: PUSH1 0x40
00000a1a: MLOAD
00000a1b: PUSH3 0x461bcd
00000a1f: PUSH1 0xe5
00000a21: SHL
00000a22: DUP2
00000a23: MSTORE
00000a24: PUSH1 0x20
00000a26: PUSH1 0x04
00000a28: DUP3
00000a29: ADD
00000a2a: MSTORE
00000a2b: PUSH1 0x30
00000a2d: PUSH1 0x24
00000a2f: DUP3
00000a30: ADD
00000a31: MSTORE
00000a32: PUSH32 0x496e636f72726563742061646472657373206f6620636f6e7472616374207265
00000a53: PUSH1 0x44
00000a55: DUP3
00000a56: ADD
00000a57: MSTORE
00000a58: PUSH16 0x31b2b4bb32b91037b71029b1b430b4b7
00000a69: PUSH1 0x81
00000a6b: SHL
00000a6c: PUSH1 0x64
00000a6e: DUP3
00000a6f: ADD
00000a70: MSTORE
00000a71: PUSH1 0x84
00000a73: ADD
00000a74: PUSH2 0x0776
00000a77: JUMP
00000a78: JUMPDEST
00000a79: PUSH1 0x00
00000a7b: SWAP1
00000a7c: DUP2
00000a7d: MSTORE
00000a7e: PUSH1 0xcb
00000a80: PUSH1 0x20
00000a82: MSTORE
00000a83: PUSH1 0x40
00000a85: SWAP1
00000a86: KECCAK256
00000a87: DUP1
00000a88: SLOAD
00000a89: PUSH1 0x01
00000a8b: PUSH1 0x01
00000a8d: PUSH1 0xa0
00000a8f: SHL
00000a90: SUB
00000a91: NOT
00000a92: AND
00000a93: PUSH1 0x01
00000a95: PUSH1 0x01
00000a97: PUSH1 0xa0
00000a99: SHL
00000a9a: SUB
00000a9b: SWAP3
00000a9c: SWAP1
00000a9d: SWAP3
00000a9e: AND
00000a9f: SWAP2
00000aa0: SWAP1
00000aa1: SWAP2
00000aa2: OR
00000aa3: SWAP1
00000aa4: SSTORE
00000aa5: POP
00000aa6: POP
00000aa7: JUMP
00000aa8: JUMPDEST
00000aa9: PUSH1 0x01
00000aab: PUSH1 0x01
00000aad: PUSH1 0xa0
00000aaf: SHL
00000ab0: SUB
00000ab1: DUP2
00000ab2: AND
00000ab3: PUSH1 0x00
00000ab5: SWAP1
00000ab6: DUP2
00000ab7: MSTORE
00000ab8: PUSH1 0xcd
00000aba: PUSH1 0x20
00000abc: SWAP1
00000abd: DUP2
00000abe: MSTORE
00000abf: PUSH1 0x40
00000ac1: DUP1
00000ac2: DUP4
00000ac3: KECCAK256
00000ac4: DUP6
00000ac5: DUP5
00000ac6: MSTORE
00000ac7: SWAP1
00000ac8: SWAP2
00000ac9: MSTORE
00000aca: DUP2
00000acb: KECCAK256
00000acc: SLOAD
00000acd: PUSH1 0xff
00000acf: AND
00000ad0: DUP1
00000ad1: ISZERO
00000ad2: PUSH2 0x0ae2
00000ad5: JUMPI
00000ad6: POP
00000ad7: PUSH2 0x0ae2
00000ada: DUP4
00000adb: DUP4
00000adc: PUSH1 0x00
00000ade: PUSH2 0x1c75
00000ae1: JUMP
00000ae2: JUMPDEST
00000ae3: SWAP4
00000ae4: SWAP3
00000ae5: POP
00000ae6: POP
00000ae7: POP
00000ae8: JUMP
00000ae9: JUMPDEST
00000aea: PUSH1 0x00
00000aec: DUP3
00000aed: DUP2
00000aee: MSTORE
00000aef: PUSH1 0x65
00000af1: PUSH1 0x20
00000af3: MSTORE
00000af4: PUSH1 0x40
00000af6: SWAP1
00000af7: KECCAK256
00000af8: PUSH1 0x01
00000afa: ADD
00000afb: SLOAD
00000afc: PUSH2 0x0b04
00000aff: DUP2
00000b00: PUSH2 0x1cbd
00000b03: JUMP
00000b04: JUMPDEST
00000b05: PUSH2 0x0b0e
00000b08: DUP4
00000b09: DUP4
00000b0a: PUSH2 0x1cca
00000b0d: JUMP
00000b0e: JUMPDEST
00000b0f: POP
00000b10: POP
00000b11: POP
00000b12: JUMP
00000b13: JUMPDEST
00000b14: PUSH2 0x0b3d
00000b17: PUSH32 0x96e3fc3be15159903e053027cff8a23f39a990e0194abcd8ac1cf1b355b8b93c
00000b38: CALLER
00000b39: PUSH2 0x1459
00000b3c: JUMP
00000b3d: JUMPDEST
00000b3e: PUSH2 0x0b89
00000b41: JUMPI
00000b42: PUSH1 0x40
00000b44: MLOAD
00000b45: PUSH3 0x461bcd
00000b49: PUSH1 0xe5
00000b4b: SHL
00000b4c: DUP2
00000b4d: MSTORE
00000b4e: PUSH1 0x20
00000b50: PUSH1 0x04
00000b52: DUP3
00000b53: ADD
00000b54: DUP2
00000b55: SWAP1
00000b56: MSTORE
00000b57: PUSH1 0x24
00000b59: DUP3
00000b5a: ADD
00000b5b: MSTORE
00000b5c: PUSH32 0x434f4e5354414e545f5345545445525f524f4c45206973207265717569726564
00000b7d: PUSH1 0x44
00000b7f: DUP3
00000b80: ADD
00000b81: MSTORE
00000b82: PUSH1 0x64
00000b84: ADD
00000b85: PUSH2 0x0776
00000b88: JUMP
00000b89: JUMPDEST
00000b8a: PUSH1 0x00
00000b8c: DUP2
00000b8d: GT
00000b8e: PUSH2 0x0bcb
00000b91: JUMPI
00000b92: PUSH1 0x40
00000b94: MLOAD
00000b95: PUSH3 0x461bcd
00000b99: PUSH1 0xe5
00000b9b: SHL
00000b9c: DUP2
00000b9d: MSTORE
00000b9e: PUSH1 0x20
00000ba0: PUSH1 0x04
00000ba2: DUP3
00000ba3: ADD
00000ba4: MSTORE
00000ba5: PUSH1 0x0f
00000ba7: PUSH1 0x24
00000ba9: DUP3
00000baa: ADD
00000bab: MSTORE
00000bac: PUSH15 0x44697669646572206973207a65726f
00000bbc: PUSH1 0x88
00000bbe: SHL
00000bbf: PUSH1 0x44
00000bc1: DUP3
00000bc2: ADD
00000bc3: MSTORE
00000bc4: PUSH1 0x64
00000bc6: ADD
00000bc7: PUSH2 0x0776
00000bca: JUMP
00000bcb: JUMPDEST
00000bcc: PUSH1 0xcf
00000bce: SLOAD
00000bcf: PUSH1 0xd0
00000bd1: SLOAD
00000bd2: PUSH1 0x40
00000bd4: DUP1
00000bd5: MLOAD
00000bd6: SWAP3
00000bd7: DUP4
00000bd8: MSTORE
00000bd9: PUSH1 0x20
00000bdb: DUP4
00000bdc: ADD
00000bdd: SWAP2
00000bde: SWAP1
00000bdf: SWAP2
00000be0: MSTORE
00000be1: DUP2
00000be2: ADD
00000be3: DUP4
00000be4: SWAP1
00000be5: MSTORE
00000be6: PUSH1 0x60
00000be8: DUP2
00000be9: ADD
00000bea: DUP3
00000beb: SWAP1
00000bec: MSTORE
00000bed: PUSH32 0x52a64da4541dabf311206f46c57caaa217b96d6647e455c52e6dd7110abf20ab
00000c0e: SWAP1
00000c0f: PUSH1 0x80
00000c11: ADD
00000c12: PUSH1 0x40
00000c14: MLOAD
00000c15: DUP1
00000c16: SWAP2
00000c17: SUB
00000c18: SWAP1
00000c19: LOG1
00000c1a: PUSH1 0xcf
00000c1c: SWAP2
00000c1d: SWAP1
00000c1e: SWAP2
00000c1f: SSTORE
00000c20: PUSH1 0xd0
00000c22: SSTORE
00000c23: JUMP
00000c24: JUMPDEST
00000c25: PUSH1 0x01
00000c27: PUSH1 0x01
00000c29: PUSH1 0xa0
00000c2b: SHL
00000c2c: SUB
00000c2d: DUP2
00000c2e: AND
00000c2f: CALLER
00000c30: EQ
00000c31: PUSH2 0x0c94
00000c34: JUMPI
00000c35: PUSH1 0x40
00000c37: MLOAD
00000c38: PUSH3 0x461bcd
00000c3c: PUSH1 0xe5
00000c3e: SHL
00000c3f: DUP2
00000c40: MSTORE
00000c41: PUSH1 0x20
00000c43: PUSH1 0x04
00000c45: DUP3
00000c46: ADD
00000c47: MSTORE
00000c48: PUSH1 0x2f
00000c4a: PUSH1 0x24
00000c4c: DUP3
00000c4d: ADD
00000c4e: MSTORE
00000c4f: PUSH32 0x416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e6365
00000c70: PUSH1 0x44
00000c72: DUP3
00000c73: ADD
00000c74: MSTORE
00000c75: PUSH15 0x103937b632b9903337b91039b2b633
00000c85: PUSH1 0x89
00000c87: SHL
00000c88: PUSH1 0x64
00000c8a: DUP3
00000c8b: ADD
00000c8c: MSTORE
00000c8d: PUSH1 0x84
00000c8f: ADD
00000c90: PUSH2 0x0776
00000c93: JUMP
00000c94: JUMPDEST
00000c95: PUSH2 0x0c9e
00000c98: DUP3
00000c99: DUP3
00000c9a: PUSH2 0x1cec
00000c9d: JUMP
00000c9e: JUMPDEST
00000c9f: POP
00000ca0: POP
00000ca1: JUMP
00000ca2: JUMPDEST
00000ca3: PUSH1 0xc9
00000ca5: SLOAD
00000ca6: PUSH1 0x40
00000ca8: MLOAD
00000ca9: PUSH4 0x35817773
00000cae: PUSH1 0xe0
00000cb0: SHL
00000cb1: DUP2
00000cb2: MSTORE
00000cb3: PUSH1 0x20
00000cb5: PUSH1 0x04
00000cb7: DUP3
00000cb8: ADD
00000cb9: MSTORE
00000cba: PUSH1 0x0f
00000cbc: PUSH1 0x24
00000cbe: DUP3
00000cbf: ADD
00000cc0: MSTORE
00000cc1: PUSH15 0x14d8da185a5b9cd25b9d195c9b985b
00000cd1: PUSH1 0x8a
00000cd3: SHL
00000cd4: PUSH1 0x44
00000cd6: DUP3
00000cd7: ADD
00000cd8: MSTORE
00000cd9: PUSH1 0x00
00000cdb: SWAP2
00000cdc: DUP3
00000cdd: SWAP2
00000cde: PUSH1 0x01
00000ce0: PUSH1 0x01
00000ce2: PUSH1 0xa0
00000ce4: SHL
00000ce5: SUB
00000ce6: SWAP1
00000ce7: SWAP2
00000ce8: AND
00000ce9: SWAP1
00000cea: PUSH4 0x35817773
00000cef: SWAP1
00000cf0: PUSH1 0x64
00000cf2: ADD
00000cf3: PUSH1 0x20
00000cf5: PUSH1 0x40
00000cf7: MLOAD
00000cf8: DUP1
00000cf9: DUP4
00000cfa: SUB
00000cfb: DUP2
00000cfc: DUP7
00000cfd: GAS
00000cfe: STATICCALL
00000cff: ISZERO
00000d00: DUP1
00000d01: ISZERO
00000d02: PUSH2 0x0d0f
00000d05: JUMPI
00000d06: RETURNDATASIZE
00000d07: PUSH1 0x00
00000d09: DUP1
00000d0a: RETURNDATACOPY
00000d0b: RETURNDATASIZE
00000d0c: PUSH1 0x00
00000d0e: REVERT
00000d0f: JUMPDEST
00000d10: POP
00000d11: POP
00000d12: POP
00000d13: POP
00000d14: PUSH1 0x40
00000d16: MLOAD
00000d17: RETURNDATASIZE
00000d18: PUSH1 0x1f
00000d1a: NOT
00000d1b: PUSH1 0x1f
00000d1d: DUP3
00000d1e: ADD
00000d1f: AND
00000d20: DUP3
00000d21: ADD
00000d22: DUP1
00000d23: PUSH1 0x40
00000d25: MSTORE
00000d26: POP
00000d27: DUP2
00000d28: ADD
00000d29: SWAP1
00000d2a: PUSH2 0x0d33
00000d2d: SWAP2
00000d2e: SWAP1
00000d2f: PUSH2 0x2744
00000d32: JUMP
00000d33: JUMPDEST
00000d34: PUSH1 0x40
00000d36: MLOAD
00000d37: PUSH4 0x47bf2805
00000d3c: PUSH1 0xe1
00000d3e: SHL
00000d3f: DUP2
00000d40: MSTORE
00000d41: PUSH1 0x01
00000d43: PUSH1 0x01
00000d45: PUSH1 0xa0
00000d47: SHL
00000d48: SUB
00000d49: DUP7
00000d4a: DUP2
00000d4b: AND
00000d4c: PUSH1 0x04
00000d4e: DUP4
00000d4f: ADD
00000d50: MSTORE
00000d51: PUSH1 0x24
00000d53: DUP3
00000d54: ADD
00000d55: DUP7
00000d56: SWAP1
00000d57: MSTORE
00000d58: SWAP2
00000d59: SWAP3
00000d5a: POP
00000d5b: SWAP1
00000d5c: DUP3
00000d5d: AND
00000d5e: SWAP1
00000d5f: PUSH4 0x8f7e500a
00000d64: SWAP1
00000d65: PUSH1 0x44
00000d67: ADD
00000d68: JUMPDEST
00000d69: PUSH1 0x20
00000d6b: PUSH1 0x40
00000d6d: MLOAD
00000d6e: DUP1
00000d6f: DUP4
00000d70: SUB
00000d71: DUP2
00000d72: DUP7
00000d73: GAS
00000d74: STATICCALL
00000d75: ISZERO
00000d76: DUP1
00000d77: ISZERO
00000d78: PUSH2 0x0d85
00000d7b: JUMPI
00000d7c: RETURNDATASIZE
00000d7d: PUSH1 0x00
00000d7f: DUP1
00000d80: RETURNDATACOPY
00000d81: RETURNDATASIZE
00000d82: PUSH1 0x00
00000d84: REVERT
00000d85: JUMPDEST
00000d86: POP
00000d87: POP
00000d88: POP
00000d89: POP
00000d8a: PUSH1 0x40
00000d8c: MLOAD
00000d8d: RETURNDATASIZE
00000d8e: PUSH1 0x1f
00000d90: NOT
00000d91: PUSH1 0x1f
00000d93: DUP3
00000d94: ADD
00000d95: AND
00000d96: DUP3
00000d97: ADD
00000d98: DUP1
00000d99: PUSH1 0x40
00000d9b: MSTORE
00000d9c: POP
00000d9d: DUP2
00000d9e: ADD
00000d9f: SWAP1
00000da0: PUSH2 0x0da9
00000da3: SWAP2
00000da4: SWAP1
00000da5: PUSH2 0x2761
00000da8: JUMP
00000da9: JUMPDEST
00000daa: SWAP5
00000dab: SWAP4
00000dac: POP
00000dad: POP
00000dae: POP
00000daf: POP
00000db0: JUMP
00000db1: JUMPDEST
00000db2: PUSH1 0x00
00000db4: SLOAD
00000db5: PUSH2 0x0100
00000db8: SWAP1
00000db9: DIV
00000dba: PUSH1 0xff
00000dbc: AND
00000dbd: ISZERO
00000dbe: DUP1
00000dbf: DUP1
00000dc0: ISZERO
00000dc1: PUSH2 0x0dd1
00000dc4: JUMPI
00000dc5: POP
00000dc6: PUSH1 0x00
00000dc8: SLOAD
00000dc9: PUSH1 0x01
00000dcb: PUSH1 0xff
00000dcd: SWAP1
00000dce: SWAP2
00000dcf: AND
00000dd0: LT
00000dd1: JUMPDEST
00000dd2: DUP1
00000dd3: PUSH2 0x0deb
00000dd6: JUMPI
00000dd7: POP
00000dd8: ADDRESS
00000dd9: EXTCODESIZE
00000dda: ISZERO
00000ddb: DUP1
00000ddc: ISZERO
00000ddd: PUSH2 0x0deb
00000de0: JUMPI
00000de1: POP
00000de2: PUSH1 0x00
00000de4: SLOAD
00000de5: PUSH1 0xff
00000de7: AND
00000de8: PUSH1 0x01
00000dea: EQ
00000deb: JUMPDEST
00000dec: PUSH2 0x0e07
00000def: JUMPI
00000df0: PUSH1 0x40
00000df2: MLOAD
00000df3: PUSH3 0x461bcd
00000df7: PUSH1 0xe5
00000df9: SHL
00000dfa: DUP2
00000dfb: MSTORE
00000dfc: PUSH1 0x04
00000dfe: ADD
00000dff: PUSH2 0x0776
00000e02: SWAP1
00000e03: PUSH2 0x2783
00000e06: JUMP
00000e07: JUMPDEST
00000e08: PUSH1 0x00
00000e0a: DUP1
00000e0b: SLOAD
00000e0c: PUSH1 0xff
00000e0e: NOT
00000e0f: AND
00000e10: PUSH1 0x01
00000e12: OR
00000e13: SWAP1
00000e14: SSTORE
00000e15: DUP1
00000e16: ISZERO
00000e17: PUSH2 0x0e2a
00000e1a: JUMPI
00000e1b: PUSH1 0x00
00000e1d: DUP1
00000e1e: SLOAD
00000e1f: PUSH2 0xff00
00000e22: NOT
00000e23: AND
00000e24: PUSH2 0x0100
00000e27: OR
00000e28: SWAP1
00000e29: SSTORE
00000e2a: JUMPDEST
00000e2b: PUSH2 0x0e33
00000e2e: DUP4
00000e2f: PUSH2 0x193a
00000e32: JUMP
00000e33: JUMPDEST
00000e34: PUSH1 0xca
00000e36: DUP1
00000e37: SLOAD
00000e38: PUSH1 0x01
00000e3a: PUSH1 0x01
00000e3c: PUSH1 0xa0
00000e3e: SHL
00000e3f: SUB
00000e40: NOT
00000e41: AND
00000e42: PUSH1 0x01
00000e44: PUSH1 0x01
00000e46: PUSH1 0xa0
00000e48: SHL
00000e49: SUB
00000e4a: DUP5
00000e4b: AND
00000e4c: OR
00000e4d: SWAP1
00000e4e: SSTORE
00000e4f: DUP1
00000e50: ISZERO
00000e51: PUSH2 0x0b0e
00000e54: JUMPI
00000e55: PUSH1 0x00
00000e57: DUP1
00000e58: SLOAD
00000e59: PUSH2 0xff00
00000e5c: NOT
00000e5d: AND
00000e5e: SWAP1
00000e5f: SSTORE
00000e60: PUSH1 0x40
00000e62: MLOAD
00000e63: PUSH1 0x01
00000e65: DUP2
00000e66: MSTORE
00000e67: PUSH32 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498
00000e88: SWAP1
00000e89: PUSH1 0x20
00000e8b: ADD
00000e8c: PUSH1 0x40
00000e8e: MLOAD
00000e8f: DUP1
00000e90: SWAP2
00000e91: SUB
00000e92: SWAP1
00000e93: LOG1
00000e94: POP
00000e95: POP
00000e96: POP
00000e97: JUMP
00000e98: JUMPDEST
00000e99: PUSH1 0xca
00000e9b: SLOAD
00000e9c: PUSH1 0x00
00000e9e: SWAP1
00000e9f: PUSH1 0x01
00000ea1: PUSH1 0x01
00000ea3: PUSH1 0xa0
00000ea5: SHL
00000ea6: SUB
00000ea7: AND
00000ea8: CALLER
00000ea9: EQ
00000eaa: PUSH2 0x0ef5
00000ead: JUMPI
00000eae: PUSH1 0x40
00000eb0: MLOAD
00000eb1: PUSH3 0x461bcd
00000eb5: PUSH1 0xe5
00000eb7: SHL
00000eb8: DUP2
00000eb9: MSTORE
00000eba: PUSH1 0x20
00000ebc: PUSH1 0x04
00000ebe: DUP3
00000ebf: ADD
00000ec0: MSTORE
00000ec1: PUSH1 0x1c
00000ec3: PUSH1 0x24
00000ec5: DUP3
00000ec6: ADD
00000ec7: MSTORE
00000ec8: PUSH32 0x53656e646572206973206e6f742061204d65737361676550726f787900000000
00000ee9: PUSH1 0x44
00000eeb: DUP3
00000eec: ADD
00000eed: MSTORE
00000eee: PUSH1 0x64
00000ef0: ADD
00000ef1: PUSH2 0x0776
00000ef4: JUMP
00000ef5: JUMPDEST
00000ef6: PUSH1 0x01
00000ef8: PUSH1 0x01
00000efa: PUSH1 0xa0
00000efc: SHL
00000efd: SUB
00000efe: DUP5
00000eff: AND
00000f00: PUSH2 0x0f4b
00000f03: JUMPI
00000f04: PUSH1 0x40
00000f06: MLOAD
00000f07: PUSH3 0x461bcd
00000f0b: PUSH1 0xe5
00000f0d: SHL
00000f0e: DUP2
00000f0f: MSTORE
00000f10: PUSH1 0x20
00000f12: PUSH1 0x04
00000f14: DUP3
00000f15: ADD
00000f16: MSTORE
00000f17: PUSH1 0x18
00000f19: PUSH1 0x24
00000f1b: DUP3
00000f1c: ADD
00000f1d: MSTORE
00000f1e: PUSH32 0x4e6f64652061646472657373206d757374206265207365740000000000000000
00000f3f: PUSH1 0x44
00000f41: DUP3
00000f42: ADD
00000f43: MSTORE
00000f44: PUSH1 0x64
00000f46: ADD
00000f47: PUSH2 0x0776
00000f4a: JUMP
00000f4b: JUMPDEST
00000f4c: PUSH1 0x01
00000f4e: PUSH1 0x01
00000f50: PUSH1 0xa0
00000f52: SHL
00000f53: SUB
00000f54: DUP4
00000f55: AND
00000f56: PUSH1 0x00
00000f58: SWAP1
00000f59: DUP2
00000f5a: MSTORE
00000f5b: PUSH1 0xcd
00000f5d: PUSH1 0x20
00000f5f: SWAP1
00000f60: DUP2
00000f61: MSTORE
00000f62: PUSH1 0x40
00000f64: DUP1
00000f65: DUP4
00000f66: KECCAK256
00000f67: DUP9
00000f68: DUP5
00000f69: MSTORE
00000f6a: SWAP1
00000f6b: SWAP2
00000f6c: MSTORE
00000f6d: SWAP1
00000f6e: KECCAK256
00000f6f: SLOAD
00000f70: PUSH1 0xff
00000f72: AND
00000f73: PUSH2 0x0f7d
00000f76: JUMPI
00000f77: POP
00000f78: DUP1
00000f79: PUSH2 0x0da9
00000f7c: JUMP
00000f7d: JUMPDEST
00000f7e: PUSH1 0x00
00000f80: PUSH2 0x0f89
00000f83: DUP4
00000f84: GASPRICE
00000f85: PUSH2 0x27e7
00000f88: JUMP
00000f89: JUMPDEST
00000f8a: PUSH1 0x01
00000f8c: PUSH1 0x01
00000f8e: PUSH1 0xa0
00000f90: SHL
00000f91: SUB
00000f92: DUP6
00000f93: AND
00000f94: PUSH1 0x00
00000f96: SWAP1
00000f97: DUP2
00000f98: MSTORE
00000f99: PUSH1 0xcc
00000f9b: PUSH1 0x20
00000f9d: SWAP1
00000f9e: DUP2
00000f9f: MSTORE
00000fa0: PUSH1 0x40
00000fa2: DUP1
00000fa3: DUP4
00000fa4: KECCAK256
00000fa5: DUP11
00000fa6: DUP5
00000fa7: MSTORE
00000fa8: SWAP1
00000fa9: SWAP2
00000faa: MSTORE
00000fab: SWAP1
00000fac: KECCAK256
00000fad: SLOAD
00000fae: SWAP1
00000faf: SWAP2
00000fb0: POP
00000fb1: DUP2
00000fb2: GT
00000fb3: ISZERO
00000fb4: PUSH2 0x0fdd
00000fb7: JUMPI
00000fb8: POP
00000fb9: PUSH1 0x01
00000fbb: PUSH1 0x01
00000fbd: PUSH1 0xa0
00000fbf: SHL
00000fc0: SUB
00000fc1: DUP4
00000fc2: AND
00000fc3: PUSH1 0x00
00000fc5: SWAP1
00000fc6: DUP2
00000fc7: MSTORE
00000fc8: PUSH1 0xcc
00000fca: PUSH1 0x20
00000fcc: SWAP1
00000fcd: DUP2
00000fce: MSTORE
00000fcf: PUSH1 0x40
00000fd1: DUP1
00000fd2: DUP4
00000fd3: KECCAK256
00000fd4: DUP9
00000fd5: DUP5
00000fd6: MSTORE
00000fd7: SWAP1
00000fd8: SWAP2
00000fd9: MSTORE
00000fda: SWAP1
00000fdb: KECCAK256
00000fdc: SLOAD
00000fdd: JUMPDEST
00000fde: PUSH1 0x01
00000fe0: PUSH1 0x01
00000fe2: PUSH1 0xa0
00000fe4: SHL
00000fe5: SUB
00000fe6: DUP5
00000fe7: AND
00000fe8: PUSH1 0x00
00000fea: SWAP1
00000feb: DUP2
00000fec: MSTORE
00000fed: PUSH1 0xcc
00000fef: PUSH1 0x20
00000ff1: SWAP1
00000ff2: DUP2
00000ff3: MSTORE
00000ff4: PUSH1 0x40
00000ff6: DUP1
00000ff7: DUP4
00000ff8: KECCAK256
00000ff9: DUP10
00000ffa: DUP5
00000ffb: MSTORE
00000ffc: SWAP1
00000ffd: SWAP2
00000ffe: MSTORE
00000fff: SWAP1
00001000: KECCAK256
00001001: SLOAD
00001002: PUSH2 0x100c
00001005: SWAP1
00001006: DUP3
00001007: SWAP1
00001008: PUSH2 0x27fe
0000100b: JUMP
0000100c: JUMPDEST
0000100d: PUSH1 0x01
0000100f: PUSH1 0x01
00001011: PUSH1 0xa0
00001013: SHL
00001014: SUB
00001015: DUP6
00001016: AND
00001017: PUSH1 0x00
00001019: SWAP1
0000101a: DUP2
0000101b: MSTORE
0000101c: PUSH1 0xcc
0000101e: PUSH1 0x20
00001020: SWAP1
00001021: DUP2
00001022: MSTORE
00001023: PUSH1 0x40
00001025: DUP1
00001026: DUP4
00001027: KECCAK256
00001028: DUP11
00001029: DUP5
0000102a: MSTORE
0000102b: SWAP1
0000102c: SWAP2
0000102d: MSTORE
0000102e: DUP2
0000102f: KECCAK256
00001030: SWAP2
00001031: SWAP1
00001032: SWAP2
00001033: SSTORE
00001034: PUSH2 0x1040
00001037: SWAP1
00001038: DUP8
00001039: SWAP1
0000103a: DUP7
0000103b: SWAP1
0000103c: PUSH2 0x1c75
0000103f: JUMP
00001040: JUMPDEST
00001041: PUSH2 0x10dd
00001044: JUMPI
00001045: PUSH1 0x01
00001047: PUSH1 0x01
00001049: PUSH1 0xa0
0000104b: SHL
0000104c: SUB
0000104d: DUP1
0000104e: DUP6
0000104f: AND
00001050: PUSH1 0x00
00001052: SWAP1
00001053: DUP2
00001054: MSTORE
00001055: PUSH1 0xcd
00001057: PUSH1 0x20
00001059: SWAP1
0000105a: DUP2
0000105b: MSTORE
0000105c: PUSH1 0x40
0000105e: DUP1
0000105f: DUP4
00001060: KECCAK256
00001061: DUP11
00001062: DUP5
00001063: MSTORE
00001064: SWAP1
00001065: SWAP2
00001066: MSTORE
00001067: SWAP1
00001068: KECCAK256
00001069: DUP1
0000106a: SLOAD
0000106b: PUSH1 0xff
0000106d: NOT
0000106e: AND
0000106f: SWAP1
00001070: SSTORE
00001071: PUSH1 0xca
00001073: SLOAD
00001074: AND
00001075: PUSH4 0x94489202
0000107a: DUP8
0000107b: PUSH2 0x1083
0000107e: DUP2
0000107f: PUSH2 0x13b5
00001082: JUMP
00001083: JUMPDEST
00001084: PUSH2 0x108c
00001087: DUP9
00001088: PUSH2 0x1d0e
0000108b: JUMP
0000108c: JUMPDEST
0000108d: PUSH1 0x40
0000108f: MLOAD
00001090: DUP5
00001091: PUSH4 0xffffffff
00001096: AND
00001097: PUSH1 0xe0
00001099: SHL
0000109a: DUP2
0000109b: MSTORE
0000109c: PUSH1 0x04
0000109e: ADD
0000109f: PUSH2 0x10aa
000010a2: SWAP4
000010a3: SWAP3
000010a4: SWAP2
000010a5: SWAP1
000010a6: PUSH2 0x2861
000010a9: JUMP
000010aa: JUMPDEST
000010ab: PUSH1 0x00
000010ad: PUSH1 0x40
000010af: MLOAD
000010b0: DUP1
000010b1: DUP4
000010b2: SUB
000010b3: DUP2
000010b4: PUSH1 0x00
000010b6: DUP8
000010b7: DUP1
000010b8: EXTCODESIZE
000010b9: ISZERO
000010ba: DUP1
000010bb: ISZERO
000010bc: PUSH2 0x10c4
000010bf: JUMPI
000010c0: PUSH1 0x00
000010c2: DUP1
000010c3: REVERT
000010c4: JUMPDEST
000010c5: POP
000010c6: GAS
000010c7: CALL
000010c8: ISZERO
000010c9: DUP1
000010ca: ISZERO
000010cb: PUSH2 0x10d8
000010ce: JUMPI
000010cf: RETURNDATASIZE
000010d0: PUSH1 0x00
000010d2: DUP1
000010d3: RETURNDATACOPY
000010d4: RETURNDATASIZE
000010d5: PUSH1 0x00
000010d7: REVERT
000010d8: JUMPDEST
000010d9: POP
000010da: POP
000010db: POP
000010dc: POP
000010dd: JUMPDEST
000010de: PUSH2 0x10f0
000010e1: PUSH1 0x01
000010e3: PUSH1 0x01
000010e5: PUSH1 0xa0
000010e7: SHL
000010e8: SUB
000010e9: DUP7
000010ea: AND
000010eb: DUP3
000010ec: PUSH2 0x1d1b
000010ef: JUMP
000010f0: JUMPDEST
000010f1: GASPRICE
000010f2: DUP2
000010f3: PUSH2 0x10fc
000010f6: DUP6
000010f7: DUP4
000010f8: PUSH2 0x27e7
000010fb: JUMP
000010fc: JUMPDEST
000010fd: PUSH2 0x1106
00001100: SWAP2
00001101: SWAP1
00001102: PUSH2 0x27fe
00001105: JUMP
00001106: JUMPDEST
00001107: PUSH2 0x1110
0000110a: SWAP2
0000110b: SWAP1
0000110c: PUSH2 0x2894
0000110f: JUMP
00001110: JUMPDEST
00001111: SWAP7
00001112: SWAP6
00001113: POP
00001114: POP
00001115: POP
00001116: POP
00001117: POP
00001118: POP
00001119: JUMP
0000111a: JUMPDEST
0000111b: PUSH1 0x00
0000111d: PUSH2 0x115b
00001120: DUP4
00001121: DUP4
00001122: DUP1
00001123: DUP1
00001124: PUSH1 0x1f
00001126: ADD
00001127: PUSH1 0x20
00001129: DUP1
0000112a: SWAP2
0000112b: DIV
0000112c: MUL
0000112d: PUSH1 0x20
0000112f: ADD
00001130: PUSH1 0x40
00001132: MLOAD
00001133: SWAP1
00001134: DUP2
00001135: ADD
00001136: PUSH1 0x40
00001138: MSTORE
00001139: DUP1
0000113a: SWAP4
0000113b: SWAP3
0000113c: SWAP2
0000113d: SWAP1
0000113e: DUP2
0000113f: DUP2
00001140: MSTORE
00001141: PUSH1 0x20
00001143: ADD
00001144: DUP4
00001145: DUP4
00001146: DUP1
00001147: DUP3
00001148: DUP5
00001149: CALLDATACOPY
0000114a: PUSH1 0x00
0000114c: SWAP3
0000114d: ADD
0000114e: SWAP2
0000114f: SWAP1
00001150: SWAP2
00001151: MSTORE
00001152: POP
00001153: PUSH2 0x1c45
00001156: SWAP3
00001157: POP
00001158: POP
00001159: POP
0000115a: JUMP
0000115b: JUMPDEST
0000115c: SWAP1
0000115d: POP
0000115e: PUSH2 0x1175
00001161: PUSH1 0x00
00001163: DUP1
00001164: MLOAD
00001165: PUSH1 0x20
00001167: PUSH2 0x2a15
0000116a: DUP4
0000116b: CODECOPY
0000116c: DUP2
0000116d: MLOAD
0000116e: SWAP2
0000116f: MSTORE
00001170: CALLER
00001171: PUSH2 0x1459
00001174: JUMP
00001175: JUMPDEST
00001176: DUP1
00001177: PUSH2 0x1185
0000117a: JUMPI
0000117b: POP
0000117c: PUSH2 0x1185
0000117f: CALLER
00001180: DUP3
00001181: PUSH2 0x0ca2
00001184: JUMP
00001185: JUMPDEST
00001186: PUSH2 0x11c9
00001189: JUMPI
0000118a: PUSH1 0x40
0000118c: MLOAD
0000118d: PUSH3 0x461bcd
00001191: PUSH1 0xe5
00001193: SHL
00001194: DUP2
00001195: MSTORE
00001196: PUSH1 0x20
00001198: PUSH1 0x04
0000119a: DUP3
0000119b: ADD
0000119c: MSTORE
0000119d: PUSH1 0x15
0000119f: PUSH1 0x24
000011a1: DUP3
000011a2: ADD
000011a3: MSTORE
000011a4: PUSH21 0x2737ba1030baba3437b934bd32b21031b0b63632b9
000011ba: PUSH1 0x59
000011bc: SHL
000011bd: PUSH1 0x44
000011bf: DUP3
000011c0: ADD
000011c1: MSTORE
000011c2: PUSH1 0x64
000011c4: ADD
000011c5: PUSH2 0x0776
000011c8: JUMP
000011c9: JUMPDEST
000011ca: PUSH1 0x00
000011cc: DUP2
000011cd: DUP2
000011ce: MSTORE
000011cf: PUSH1 0xcb
000011d1: PUSH1 0x20
000011d3: MSTORE
000011d4: PUSH1 0x40
000011d6: SWAP1
000011d7: KECCAK256
000011d8: SLOAD
000011d9: PUSH1 0x01
000011db: PUSH1 0x01
000011dd: PUSH1 0xa0
000011df: SHL
000011e0: SUB
000011e1: AND
000011e2: PUSH2 0x1226
000011e5: JUMPI
000011e6: PUSH1 0x40
000011e8: MLOAD
000011e9: PUSH3 0x461bcd
000011ed: PUSH1 0xe5
000011ef: SHL
000011f0: DUP2
000011f1: MSTORE
000011f2: PUSH1 0x20
000011f4: PUSH1 0x04
000011f6: DUP3
000011f7: ADD
000011f8: MSTORE
000011f9: PUSH1 0x16
000011fb: PUSH1 0x24
000011fd: DUP3
000011fe: ADD
000011ff: MSTORE
00001200: PUSH22 0x14d2d053114818da185a5b881a5cc81b9bdd081cd95d
00001217: PUSH1 0x52
00001219: SHL
0000121a: PUSH1 0x44
0000121c: DUP3
0000121d: ADD
0000121e: MSTORE
0000121f: PUSH1 0x64
00001221: ADD
00001222: PUSH2 0x0776
00001225: JUMP
00001226: JUMPDEST
00001227: PUSH1 0x00
00001229: SWAP1
0000122a: DUP2
0000122b: MSTORE
0000122c: PUSH1 0xcb
0000122e: PUSH1 0x20
00001230: MSTORE
00001231: PUSH1 0x40
00001233: SWAP1
00001234: KECCAK256
00001235: DUP1
00001236: SLOAD
00001237: PUSH1 0x01
00001239: PUSH1 0x01
0000123b: PUSH1 0xa0
0000123d: SHL
0000123e: SUB
0000123f: NOT
00001240: AND
00001241: SWAP1
00001242: SSTORE
00001243: POP
00001244: POP
00001245: JUMP
00001246: JUMPDEST
00001247: PUSH2 0x1270
0000124a: PUSH32 0x96e3fc3be15159903e053027cff8a23f39a990e0194abcd8ac1cf1b355b8b93c
0000126b: CALLER
0000126c: PUSH2 0x1459
0000126f: JUMP
00001270: JUMPDEST
00001271: PUSH2 0x12bc
00001274: JUMPI
00001275: PUSH1 0x40
00001277: MLOAD
00001278: PUSH3 0x461bcd
0000127c: PUSH1 0xe5
0000127e: SHL
0000127f: DUP2
00001280: MSTORE
00001281: PUSH1 0x20
00001283: PUSH1 0x04
00001285: DUP3
00001286: ADD
00001287: DUP2
00001288: SWAP1
00001289: MSTORE
0000128a: PUSH1 0x24
0000128c: DUP3
0000128d: ADD
0000128e: MSTORE
0000128f: PUSH32 0x434f4e5354414e545f5345545445525f524f4c45206973207265717569726564
000012b0: PUSH1 0x44
000012b2: DUP3
000012b3: ADD
000012b4: MSTORE
000012b5: PUSH1 0x64
000012b7: ADD
000012b8: PUSH2 0x0776
000012bb: JUMP
000012bc: JUMPDEST
000012bd: PUSH1 0xce
000012bf: SLOAD
000012c0: PUSH1 0x40
000012c2: DUP1
000012c3: MLOAD
000012c4: SWAP2
000012c5: DUP3
000012c6: MSTORE
000012c7: PUSH1 0x20
000012c9: DUP3
000012ca: ADD
000012cb: DUP4
000012cc: SWAP1
000012cd: MSTORE
000012ce: PUSH32 0x331f224b2912576029359714fd8a4f953651fb48b042c6c23f8da99bab035a43
000012ef: SWAP2
000012f0: ADD
000012f1: PUSH1 0x40
000012f3: MLOAD
000012f4: DUP1
000012f5: SWAP2
000012f6: SUB
000012f7: SWAP1
000012f8: LOG1
000012f9: PUSH1 0xce
000012fb: SSTORE
000012fc: JUMP
000012fd: JUMPDEST
000012fe: PUSH1 0x00
00001300: GASPRICE
00001301: PUSH1 0x00
00001303: SUB
00001304: PUSH2 0x1346
00001307: JUMPI
00001308: PUSH1 0x40
0000130a: MLOAD
0000130b: PUSH3 0x461bcd
0000130f: PUSH1 0xe5
00001311: SHL
00001312: DUP2
00001313: MSTORE
00001314: PUSH1 0x20
00001316: PUSH1 0x04
00001318: DUP3
00001319: ADD
0000131a: MSTORE
0000131b: PUSH1 0x14
0000131d: PUSH1 0x24
0000131f: DUP3
00001320: ADD
00001321: MSTORE
00001322: PUSH20 0x11d85cc81c1c9a58d9481a5cc81b9bdd081cd95d
00001337: PUSH1 0x62
00001339: SHL
0000133a: PUSH1 0x44
0000133c: DUP3
0000133d: ADD
0000133e: MSTORE
0000133f: PUSH1 0x64
00001341: ADD
00001342: PUSH2 0x0776
00001345: JUMP
00001346: JUMPDEST
00001347: PUSH1 0x00
00001349: PUSH2 0x1350
0000134c: PUSH2 0x1e34
0000134f: JUMP
00001350: JUMPDEST
00001351: PUSH1 0x01
00001353: PUSH1 0x01
00001355: PUSH1 0xa0
00001357: SHL
00001358: SUB
00001359: DUP5
0000135a: AND
0000135b: PUSH1 0x00
0000135d: SWAP1
0000135e: DUP2
0000135f: MSTORE
00001360: PUSH1 0xcc
00001362: PUSH1 0x20
00001364: SWAP1
00001365: DUP2
00001366: MSTORE
00001367: PUSH1 0x40
00001369: DUP1
0000136a: DUP4
0000136b: KECCAK256
0000136c: DUP9
0000136d: DUP5
0000136e: MSTORE
0000136f: SWAP1
00001370: SWAP2
00001371: MSTORE
00001372: SWAP1
00001373: KECCAK256
00001374: SLOAD
00001375: SWAP1
00001376: SWAP2
00001377: POP
00001378: DUP2
00001379: GT
0000137a: PUSH2 0x1387
0000137d: JUMPI
0000137e: PUSH1 0x00
00001380: SWAP2
00001381: POP
00001382: POP
00001383: PUSH2 0x0717
00001386: JUMP
00001387: JUMPDEST
00001388: PUSH1 0x01
0000138a: PUSH1 0x01
0000138c: PUSH1 0xa0
0000138e: SHL
0000138f: SUB
00001390: DUP4
00001391: AND
00001392: PUSH1 0x00
00001394: SWAP1
00001395: DUP2
00001396: MSTORE
00001397: PUSH1 0xcc
00001399: PUSH1 0x20
0000139b: SWAP1
0000139c: DUP2
0000139d: MSTORE
0000139e: PUSH1 0x40
000013a0: DUP1
000013a1: DUP4
000013a2: KECCAK256
000013a3: DUP8
000013a4: DUP5
000013a5: MSTORE
000013a6: SWAP1
000013a7: SWAP2
000013a8: MSTORE
000013a9: SWAP1
000013aa: KECCAK256
000013ab: SLOAD
000013ac: PUSH2 0x0da9
000013af: SWAP1
000013b0: DUP3
000013b1: PUSH2 0x27fe
000013b4: JUMP
000013b5: JUMPDEST
000013b6: PUSH1 0x00
000013b8: DUP2
000013b9: DUP2
000013ba: MSTORE
000013bb: PUSH1 0xcb
000013bd: PUSH1 0x20
000013bf: MSTORE
000013c0: PUSH1 0x40
000013c2: DUP2
000013c3: KECCAK256
000013c4: SLOAD
000013c5: PUSH1 0x01
000013c7: PUSH1 0x01
000013c9: PUSH1 0xa0
000013cb: SHL
000013cc: SUB
000013cd: AND
000013ce: PUSH2 0x1425
000013d1: JUMPI
000013d2: PUSH1 0x40
000013d4: MLOAD
000013d5: PUSH3 0x461bcd
000013d9: PUSH1 0xe5
000013db: SHL
000013dc: DUP2
000013dd: MSTORE
000013de: PUSH1 0x20
000013e0: PUSH1 0x04
000013e2: DUP3
000013e3: ADD
000013e4: MSTORE
000013e5: PUSH1 0x24
000013e7: DUP1
000013e8: DUP3
000013e9: ADD
000013ea: MSTORE
000013eb: PUSH32 0x44657374696e6174696f6e20636f6e7472616374206d75737420626520646566
0000140c: PUSH1 0x44
0000140e: DUP3
0000140f: ADD
00001410: MSTORE
00001411: PUSH4 0x1a5b9959
00001416: PUSH1 0xe2
00001418: SHL
00001419: PUSH1 0x64
0000141b: DUP3
0000141c: ADD
0000141d: MSTORE
0000141e: PUSH1 0x84
00001420: ADD
00001421: PUSH2 0x0776
00001424: JUMP
00001425: JUMPDEST
00001426: POP
00001427: PUSH1 0x00
00001429: SWAP1
0000142a: DUP2
0000142b: MSTORE
0000142c: PUSH1 0xcb
0000142e: PUSH1 0x20
00001430: MSTORE
00001431: PUSH1 0x40
00001433: SWAP1
00001434: KECCAK256
00001435: SLOAD
00001436: PUSH1 0x01
00001438: PUSH1 0x01
0000143a: PUSH1 0xa0
0000143c: SHL
0000143d: SUB
0000143e: AND
0000143f: SWAP1
00001440: JUMP
00001441: JUMPDEST
00001442: PUSH1 0x00
00001444: DUP3
00001445: DUP2
00001446: MSTORE
00001447: PUSH1 0x97
00001449: PUSH1 0x20
0000144b: MSTORE
0000144c: PUSH1 0x40
0000144e: DUP2
0000144f: KECCAK256
00001450: PUSH2 0x0ae2
00001453: SWAP1
00001454: DUP4
00001455: PUSH2 0x1e63
00001458: JUMP
00001459: JUMPDEST
0000145a: PUSH1 0x00
0000145c: SWAP2
0000145d: DUP3
0000145e: MSTORE
0000145f: PUSH1 0x65
00001461: PUSH1 0x20
00001463: SWAP1
00001464: DUP2
00001465: MSTORE
00001466: PUSH1 0x40
00001468: DUP1
00001469: DUP5
0000146a: KECCAK256
0000146b: PUSH1 0x01
0000146d: PUSH1 0x01
0000146f: PUSH1 0xa0
00001471: SHL
00001472: SUB
00001473: SWAP4
00001474: SWAP1
00001475: SWAP4
00001476: AND
00001477: DUP5
00001478: MSTORE
00001479: SWAP2
0000147a: SWAP1
0000147b: MSTORE
0000147c: SWAP1
0000147d: KECCAK256
0000147e: SLOAD
0000147f: PUSH1 0xff
00001481: AND
00001482: SWAP1
00001483: JUMP
00001484: JUMPDEST
00001485: PUSH1 0x00
00001487: PUSH2 0x14c5
0000148a: DUP5
0000148b: DUP5
0000148c: DUP1
0000148d: DUP1
0000148e: PUSH1 0x1f
00001490: ADD
00001491: PUSH1 0x20
00001493: DUP1
00001494: SWAP2
00001495: DIV
00001496: MUL
00001497: PUSH1 0x20
00001499: ADD
0000149a: PUSH1 0x40
0000149c: MLOAD
0000149d: SWAP1
0000149e: DUP2
0000149f: ADD
000014a0: PUSH1 0x40
000014a2: MSTORE
000014a3: DUP1
000014a4: SWAP4
000014a5: SWAP3
000014a6: SWAP2
000014a7: SWAP1
000014a8: DUP2
000014a9: DUP2
000014aa: MSTORE
000014ab: PUSH1 0x20
000014ad: ADD
000014ae: DUP4
000014af: DUP4
000014b0: DUP1
000014b1: DUP3
000014b2: DUP5
000014b3: CALLDATACOPY
000014b4: PUSH1 0x00
000014b6: SWAP3
000014b7: ADD
000014b8: SWAP2
000014b9: SWAP1
000014ba: SWAP2
000014bb: MSTORE
000014bc: POP
000014bd: PUSH2 0x1c45
000014c0: SWAP3
000014c1: POP
000014c2: POP
000014c3: POP
000014c4: JUMP
000014c5: JUMPDEST
000014c6: CALLER
000014c7: PUSH1 0x00
000014c9: SWAP1
000014ca: DUP2
000014cb: MSTORE
000014cc: PUSH1 0xcc
000014ce: PUSH1 0x20
000014d0: SWAP1
000014d1: DUP2
000014d2: MSTORE
000014d3: PUSH1 0x40
000014d5: DUP1
000014d6: DUP4
000014d7: KECCAK256
000014d8: DUP5
000014d9: DUP5
000014da: MSTORE
000014db: SWAP1
000014dc: SWAP2
000014dd: MSTORE
000014de: SWAP1
000014df: KECCAK256
000014e0: SLOAD
000014e1: SWAP1
000014e2: SWAP2
000014e3: POP
000014e4: DUP3
000014e5: GT
000014e6: ISZERO
000014e7: PUSH2 0x1527
000014ea: JUMPI
000014eb: PUSH1 0x40
000014ed: MLOAD
000014ee: PUSH3 0x461bcd
000014f2: PUSH1 0xe5
000014f4: SHL
000014f5: DUP2
000014f6: MSTORE
000014f7: PUSH1 0x20
000014f9: PUSH1 0x04
000014fb: DUP3
000014fc: ADD
000014fd: MSTORE
000014fe: PUSH1 0x12
00001500: PUSH1 0x24
00001502: DUP3
00001503: ADD
00001504: MSTORE
00001505: PUSH18 0x42616c616e636520697320746f6f206c6f77
00001518: PUSH1 0x70
0000151a: SHL
0000151b: PUSH1 0x44
0000151d: DUP3
0000151e: ADD
0000151f: MSTORE
00001520: PUSH1 0x64
00001522: ADD
00001523: PUSH2 0x0776
00001526: JUMP
00001527: JUMPDEST
00001528: PUSH1 0xca
0000152a: PUSH1 0x00
0000152c: SWAP1
0000152d: SLOAD
0000152e: SWAP1
0000152f: PUSH2 0x0100
00001532: EXP
00001533: SWAP1
00001534: DIV
00001535: PUSH1 0x01
00001537: PUSH1 0x01
00001539: PUSH1 0xa0
0000153b: SHL
0000153c: SUB
0000153d: AND
0000153e: PUSH1 0x01
00001540: PUSH1 0x01
00001542: PUSH1 0xa0
00001544: SHL
00001545: SUB
00001546: AND
00001547: PUSH4 0x1cf5379d
0000154c: PUSH1 0x40
0000154e: MLOAD
0000154f: DUP2
00001550: PUSH4 0xffffffff
00001555: AND
00001556: PUSH1 0xe0
00001558: SHL
00001559: DUP2
0000155a: MSTORE
0000155b: PUSH1 0x04
0000155d: ADD
0000155e: PUSH1 0x20
00001560: PUSH1 0x40
00001562: MLOAD
00001563: DUP1
00001564: DUP4
00001565: SUB
00001566: DUP2
00001567: DUP7
00001568: GAS
00001569: STATICCALL
0000156a: ISZERO
0000156b: DUP1
0000156c: ISZERO
0000156d: PUSH2 0x157a
00001570: JUMPI
00001571: RETURNDATASIZE
00001572: PUSH1 0x00
00001574: DUP1
00001575: RETURNDATACOPY
00001576: RETURNDATASIZE
00001577: PUSH1 0x00
00001579: REVERT
0000157a: JUMPDEST
0000157b: POP
0000157c: POP
0000157d: POP
0000157e: POP
0000157f: PUSH1 0x40
00001581: MLOAD
00001582: RETURNDATASIZE
00001583: PUSH1 0x1f
00001585: NOT
00001586: PUSH1 0x1f
00001588: DUP3
00001589: ADD
0000158a: AND
0000158b: DUP3
0000158c: ADD
0000158d: DUP1
0000158e: PUSH1 0x40
00001590: MSTORE
00001591: POP
00001592: DUP2
00001593: ADD
00001594: SWAP1
00001595: PUSH2 0x159e
00001598: SWAP2
00001599: SWAP1
0000159a: PUSH2 0x2761
0000159d: JUMP
0000159e: JUMPDEST
0000159f: ISZERO
000015a0: PUSH2 0x15e4
000015a3: JUMPI
000015a4: PUSH1 0x40
000015a6: MLOAD
000015a7: PUSH3 0x461bcd
000015ab: PUSH1 0xe5
000015ad: SHL
000015ae: DUP2
000015af: MSTORE
000015b0: PUSH1 0x20
000015b2: PUSH1 0x04
000015b4: DUP3
000015b5: ADD
000015b6: MSTORE
000015b7: PUSH1 0x16
000015b9: PUSH1 0x24
000015bb: DUP3
000015bc: ADD
000015bd: MSTORE
000015be: PUSH22 0x4d65737361676520697320696e2070726f6772657373
000015d5: PUSH1 0x50
000015d7: SHL
000015d8: PUSH1 0x44
000015da: DUP3
000015db: ADD
000015dc: MSTORE
000015dd: PUSH1 0x64
000015df: ADD
000015e0: PUSH2 0x0776
000015e3: JUMP
000015e4: JUMPDEST
000015e5: CALLER
000015e6: PUSH1 0x00
000015e8: SWAP1
000015e9: DUP2
000015ea: MSTORE
000015eb: PUSH1 0xcc
000015ed: PUSH1 0x20
000015ef: SWAP1
000015f0: DUP2
000015f1: MSTORE
000015f2: PUSH1 0x40
000015f4: DUP1
000015f5: DUP4
000015f6: KECCAK256
000015f7: DUP5
000015f8: DUP5
000015f9: MSTORE
000015fa: SWAP1
000015fb: SWAP2
000015fc: MSTORE
000015fd: SWAP1
000015fe: KECCAK256
000015ff: SLOAD
00001600: PUSH2 0x160a
00001603: SWAP1
00001604: DUP4
00001605: SWAP1
00001606: PUSH2 0x27fe
00001609: JUMP
0000160a: JUMPDEST
0000160b: CALLER
0000160c: PUSH1 0x00
0000160e: DUP2
0000160f: DUP2
00001610: MSTORE
00001611: PUSH1 0xcc
00001613: PUSH1 0x20
00001615: SWAP1
00001616: DUP2
00001617: MSTORE
00001618: PUSH1 0x40
0000161a: DUP1
0000161b: DUP4
0000161c: KECCAK256
0000161d: DUP7
0000161e: DUP5
0000161f: MSTORE
00001620: SWAP1
00001621: SWAP2
00001622: MSTORE
00001623: DUP2
00001624: KECCAK256
00001625: SWAP3
00001626: SWAP1
00001627: SWAP3
00001628: SSTORE
00001629: PUSH2 0x1634
0000162c: SWAP2
0000162d: DUP4
0000162e: SWAP2
0000162f: SWAP1
00001630: PUSH2 0x1c75
00001633: JUMP
00001634: JUMPDEST
00001635: ISZERO
00001636: DUP1
00001637: ISZERO
00001638: PUSH2 0x165b
0000163b: JUMPI
0000163c: POP
0000163d: CALLER
0000163e: PUSH1 0x00
00001640: SWAP1
00001641: DUP2
00001642: MSTORE
00001643: PUSH1 0xcd
00001645: PUSH1 0x20
00001647: SWAP1
00001648: DUP2
00001649: MSTORE
0000164a: PUSH1 0x40
0000164c: DUP1
0000164d: DUP4
0000164e: KECCAK256
0000164f: DUP5
00001650: DUP5
00001651: MSTORE
00001652: SWAP1
00001653: SWAP2
00001654: MSTORE
00001655: SWAP1
00001656: KECCAK256
00001657: SLOAD
00001658: PUSH1 0xff
0000165a: AND
0000165b: JUMPDEST
0000165c: ISZERO
0000165d: PUSH2 0x16f7
00001660: JUMPI
00001661: CALLER
00001662: PUSH1 0x00
00001664: SWAP1
00001665: DUP2
00001666: MSTORE
00001667: PUSH1 0xcd
00001669: PUSH1 0x20
0000166b: SWAP1
0000166c: DUP2
0000166d: MSTORE
0000166e: PUSH1 0x40
00001670: DUP1
00001671: DUP4
00001672: KECCAK256
00001673: DUP5
00001674: DUP5
00001675: MSTORE
00001676: SWAP1
00001677: SWAP2
00001678: MSTORE
00001679: SWAP1
0000167a: KECCAK256
0000167b: DUP1
0000167c: SLOAD
0000167d: PUSH1 0xff
0000167f: NOT
00001680: AND
00001681: SWAP1
00001682: SSTORE
00001683: PUSH1 0xca
00001685: SLOAD
00001686: PUSH1 0x01
00001688: PUSH1 0x01
0000168a: PUSH1 0xa0
0000168c: SHL
0000168d: SUB
0000168e: AND
0000168f: PUSH4 0x94489202
00001694: DUP3
00001695: PUSH2 0x169d
00001698: DUP2
00001699: PUSH2 0x13b5
0000169c: JUMP
0000169d: JUMPDEST
0000169e: PUSH2 0x16a6
000016a1: CALLER
000016a2: PUSH2 0x1d0e
000016a5: JUMP
000016a6: JUMPDEST
000016a7: PUSH1 0x40
000016a9: MLOAD
000016aa: DUP5
000016ab: PUSH4 0xffffffff
000016b0: AND
000016b1: PUSH1 0xe0
000016b3: SHL
000016b4: DUP2
000016b5: MSTORE
000016b6: PUSH1 0x04
000016b8: ADD
000016b9: PUSH2 0x16c4
000016bc: SWAP4
000016bd: SWAP3
000016be: SWAP2
000016bf: SWAP1
000016c0: PUSH2 0x2861
000016c3: JUMP
000016c4: JUMPDEST
000016c5: PUSH1 0x00
000016c7: PUSH1 0x40
000016c9: MLOAD
000016ca: DUP1
000016cb: DUP4
000016cc: SUB
000016cd: DUP2
000016ce: PUSH1 0x00
000016d0: DUP8
000016d1: DUP1
000016d2: EXTCODESIZE
000016d3: ISZERO
000016d4: DUP1
000016d5: ISZERO
000016d6: PUSH2 0x16de
000016d9: JUMPI
000016da: PUSH1 0x00
000016dc: DUP1
000016dd: REVERT
000016de: JUMPDEST
000016df: POP
000016e0: GAS
000016e1: CALL
000016e2: ISZERO
000016e3: DUP1
000016e4: ISZERO
000016e5: PUSH2 0x16f2
000016e8: JUMPI
000016e9: RETURNDATASIZE
000016ea: PUSH1 0x00
000016ec: DUP1
000016ed: RETURNDATACOPY
000016ee: RETURNDATASIZE
000016ef: PUSH1 0x00
000016f1: REVERT
000016f2: JUMPDEST
000016f3: POP
000016f4: POP
000016f5: POP
000016f6: POP
000016f7: JUMPDEST
000016f8: PUSH2 0x1701
000016fb: CALLER
000016fc: DUP4
000016fd: PUSH2 0x1d1b
00001700: JUMP
00001701: JUMPDEST
00001702: POP
00001703: POP
00001704: POP
00001705: POP
00001706: JUMP
00001707: JUMPDEST
00001708: PUSH1 0xc9
0000170a: SLOAD
0000170b: PUSH1 0x40
0000170d: MLOAD
0000170e: PUSH4 0x35817773
00001713: PUSH1 0xe0
00001715: SHL
00001716: DUP2
00001717: MSTORE
00001718: PUSH1 0x20
0000171a: PUSH1 0x04
0000171c: DUP3
0000171d: ADD
0000171e: MSTORE
0000171f: PUSH1 0x0f
00001721: PUSH1 0x24
00001723: DUP3
00001724: ADD
00001725: MSTORE
00001726: PUSH15 0x14d8da185a5b9cd25b9d195c9b985b
00001736: PUSH1 0x8a
00001738: SHL
00001739: PUSH1 0x44
0000173b: DUP3
0000173c: ADD
0000173d: MSTORE
0000173e: PUSH1 0x00
00001740: SWAP2
00001741: DUP3
00001742: SWAP2
00001743: PUSH1 0x01
00001745: PUSH1 0x01
00001747: PUSH1 0xa0
00001749: SHL
0000174a: SUB
0000174b: SWAP1
0000174c: SWAP2
0000174d: AND
0000174e: SWAP1
0000174f: PUSH4 0x35817773
00001754: SWAP1
00001755: PUSH1 0x64
00001757: ADD
00001758: PUSH1 0x20
0000175a: PUSH1 0x40
0000175c: MLOAD
0000175d: DUP1
0000175e: DUP4
0000175f: SUB
00001760: DUP2
00001761: DUP7
00001762: GAS
00001763: STATICCALL
00001764: ISZERO
00001765: DUP1
00001766: ISZERO
00001767: PUSH2 0x1774
0000176a: JUMPI
0000176b: RETURNDATASIZE
0000176c: PUSH1 0x00
0000176e: DUP1
0000176f: RETURNDATACOPY
00001770: RETURNDATASIZE
00001771: PUSH1 0x00
00001773: REVERT
00001774: JUMPDEST
00001775: POP
00001776: POP
00001777: POP
00001778: POP
00001779: PUSH1 0x40
0000177b: MLOAD
0000177c: RETURNDATASIZE
0000177d: PUSH1 0x1f
0000177f: NOT
00001780: PUSH1 0x1f
00001782: DUP3
00001783: ADD
00001784: AND
00001785: DUP3
00001786: ADD
00001787: DUP1
00001788: PUSH1 0x40
0000178a: MSTORE
0000178b: POP
0000178c: DUP2
0000178d: ADD
0000178e: SWAP1
0000178f: PUSH2 0x1798
00001792: SWAP2
00001793: SWAP1
00001794: PUSH2 0x2744
00001797: JUMP
00001798: JUMPDEST
00001799: PUSH1 0x40
0000179b: MLOAD
0000179c: PUSH4 0x55189a3d
000017a1: PUSH1 0xe1
000017a3: SHL
000017a4: DUP2
000017a5: MSTORE
000017a6: PUSH1 0x04
000017a8: DUP2
000017a9: ADD
000017aa: DUP7
000017ab: SWAP1
000017ac: MSTORE
000017ad: PUSH1 0x01
000017af: PUSH1 0x01
000017b1: PUSH1 0xa0
000017b3: SHL
000017b4: SUB
000017b5: DUP6
000017b6: DUP2
000017b7: AND
000017b8: PUSH1 0x24
000017ba: DUP4
000017bb: ADD
000017bc: MSTORE
000017bd: SWAP2
000017be: SWAP3
000017bf: POP
000017c0: SWAP1
000017c1: DUP3
000017c2: AND
000017c3: SWAP1
000017c4: PUSH4 0xaa31347a
000017c9: SWAP1
000017ca: PUSH1 0x44
000017cc: ADD
000017cd: PUSH2 0x0d68
000017d0: JUMP
000017d1: JUMPDEST
000017d2: PUSH1 0x00
000017d4: DUP1
000017d5: PUSH1 0x01
000017d7: PUSH1 0x01
000017d9: PUSH1 0xa0
000017db: SHL
000017dc: SUB
000017dd: AND
000017de: PUSH1 0xcb
000017e0: PUSH1 0x00
000017e2: PUSH2 0x1820
000017e5: DUP7
000017e6: DUP7
000017e7: DUP1
000017e8: DUP1
000017e9: PUSH1 0x1f
000017eb: ADD
000017ec: PUSH1 0x20
000017ee: DUP1
000017ef: SWAP2
000017f0: DIV
000017f1: MUL
000017f2: PUSH1 0x20
000017f4: ADD
000017f5: PUSH1 0x40
000017f7: MLOAD
000017f8: SWAP1
000017f9: DUP2
000017fa: ADD
000017fb: PUSH1 0x40
000017fd: MSTORE
000017fe: DUP1
000017ff: SWAP4
00001800: SWAP3
00001801: SWAP2
00001802: SWAP1
00001803: DUP2
00001804: DUP2
00001805: MSTORE
00001806: PUSH1 0x20
00001808: ADD
00001809: DUP4
0000180a: DUP4
0000180b: DUP1
0000180c: DUP3
0000180d: DUP5
0000180e: CALLDATACOPY
0000180f: PUSH1 0x00
00001811: SWAP3
00001812: ADD
00001813: SWAP2
00001814: SWAP1
00001815: SWAP2
00001816: MSTORE
00001817: POP
00001818: PUSH2 0x1c45
0000181b: SWAP3
0000181c: POP
0000181d: POP
0000181e: POP
0000181f: JUMP
00001820: JUMPDEST
00001821: DUP2
00001822: MSTORE
00001823: PUSH1 0x20
00001825: DUP2
00001826: ADD
00001827: SWAP2
00001828: SWAP1
00001829: SWAP2
0000182a: MSTORE
0000182b: PUSH1 0x40
0000182d: ADD
0000182e: PUSH1 0x00
00001830: KECCAK256
00001831: SLOAD
00001832: PUSH1 0x01
00001834: PUSH1 0x01
00001836: PUSH1 0xa0
00001838: SHL
00001839: SUB
0000183a: AND
0000183b: EQ
0000183c: ISZERO
0000183d: SWAP4
0000183e: SWAP3
0000183f: POP
00001840: POP
00001841: POP
00001842: JUMP
00001843: JUMPDEST
00001844: PUSH1 0x00
00001846: SLOAD
00001847: PUSH2 0x0100
0000184a: SWAP1
0000184b: DIV
0000184c: PUSH1 0xff
0000184e: AND
0000184f: ISZERO
00001850: DUP1
00001851: DUP1
00001852: ISZERO
00001853: PUSH2 0x1863
00001856: JUMPI
00001857: POP
00001858: PUSH1 0x00
0000185a: SLOAD
0000185b: PUSH1 0x01
0000185d: PUSH1 0xff
0000185f: SWAP1
00001860: SWAP2
00001861: AND
00001862: LT
00001863: JUMPDEST
00001864: DUP1
00001865: PUSH2 0x187d
00001868: JUMPI
00001869: POP
0000186a: ADDRESS
0000186b: EXTCODESIZE
0000186c: ISZERO
0000186d: DUP1
0000186e: ISZERO
0000186f: PUSH2 0x187d
00001872: JUMPI
00001873: POP
00001874: PUSH1 0x00
00001876: SLOAD
00001877: PUSH1 0xff
00001879: AND
0000187a: PUSH1 0x01
0000187c: EQ
0000187d: JUMPDEST
0000187e: PUSH2 0x1899
00001881: JUMPI
00001882: PUSH1 0x40
00001884: MLOAD
00001885: PUSH3 0x461bcd
00001889: PUSH1 0xe5
0000188b: SHL
0000188c: DUP2
0000188d: MSTORE
0000188e: PUSH1 0x04
00001890: ADD
00001891: PUSH2 0x0776
00001894: SWAP1
00001895: PUSH2 0x2783
00001898: JUMP
00001899: JUMPDEST
0000189a: PUSH1 0x00
0000189c: DUP1
0000189d: SLOAD
0000189e: PUSH1 0xff
000018a0: NOT
000018a1: AND
000018a2: PUSH1 0x01
000018a4: OR
000018a5: SWAP1
000018a6: SSTORE
000018a7: DUP1
000018a8: ISZERO
000018a9: PUSH2 0x18bc
000018ac: JUMPI
000018ad: PUSH1 0x00
000018af: DUP1
000018b0: SLOAD
000018b1: PUSH2 0xff00
000018b4: NOT
000018b5: AND
000018b6: PUSH2 0x0100
000018b9: OR
000018ba: SWAP1
000018bb: SSTORE
000018bc: JUMPDEST
000018bd: PUSH2 0x18c6
000018c0: DUP5
000018c1: DUP4
000018c2: PUSH2 0x0db1
000018c5: JUMP
000018c6: JUMPDEST
000018c7: PUSH2 0x18de
000018ca: PUSH1 0x00
000018cc: DUP1
000018cd: MLOAD
000018ce: PUSH1 0x20
000018d0: PUSH2 0x2a15
000018d3: DUP4
000018d4: CODECOPY
000018d5: DUP2
000018d6: MLOAD
000018d7: SWAP2
000018d8: MSTORE
000018d9: DUP5
000018da: PUSH2 0x1e6f
000018dd: JUMP
000018de: JUMPDEST
000018df: PUSH3 0x0f4240
000018e3: PUSH1 0xce
000018e5: SSTORE
000018e6: PUSH1 0x03
000018e8: PUSH1 0xcf
000018ea: SSTORE
000018eb: PUSH1 0x02
000018ed: PUSH1 0xd0
000018ef: SSTORE
000018f0: DUP1
000018f1: ISZERO
000018f2: PUSH2 0x1701
000018f5: JUMPI
000018f6: PUSH1 0x00
000018f8: DUP1
000018f9: SLOAD
000018fa: PUSH2 0xff00
000018fd: NOT
000018fe: AND
000018ff: SWAP1
00001900: SSTORE
00001901: PUSH1 0x40
00001903: MLOAD
00001904: PUSH1 0x01
00001906: DUP2
00001907: MSTORE
00001908: PUSH32 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498
00001929: SWAP1
0000192a: PUSH1 0x20
0000192c: ADD
0000192d: PUSH1 0x40
0000192f: MLOAD
00001930: DUP1
00001931: SWAP2
00001932: SUB
00001933: SWAP1
00001934: LOG1
00001935: POP
00001936: POP
00001937: POP
00001938: POP
00001939: JUMP
0000193a: JUMPDEST
0000193b: PUSH1 0x00
0000193d: SLOAD
0000193e: PUSH2 0x0100
00001941: SWAP1
00001942: DIV
00001943: PUSH1 0xff
00001945: AND
00001946: ISZERO
00001947: DUP1
00001948: DUP1
00001949: ISZERO
0000194a: PUSH2 0x195a
0000194d: JUMPI
0000194e: POP
0000194f: PUSH1 0x00
00001951: SLOAD
00001952: PUSH1 0x01
00001954: PUSH1 0xff
00001956: SWAP1
00001957: SWAP2
00001958: AND
00001959: LT
0000195a: JUMPDEST
0000195b: DUP1
0000195c: PUSH2 0x1974
0000195f: JUMPI
00001960: POP
00001961: ADDRESS
00001962: EXTCODESIZE
00001963: ISZERO
00001964: DUP1
00001965: ISZERO
00001966: PUSH2 0x1974
00001969: JUMPI
0000196a: POP
0000196b: PUSH1 0x00
0000196d: SLOAD
0000196e: PUSH1 0xff
00001970: AND
00001971: PUSH1 0x01
00001973: EQ
00001974: JUMPDEST
00001975: PUSH2 0x1990
00001978: JUMPI
00001979: PUSH1 0x40
0000197b: MLOAD
0000197c: PUSH3 0x461bcd
00001980: PUSH1 0xe5
00001982: SHL
00001983: DUP2
00001984: MSTORE
00001985: PUSH1 0x04
00001987: ADD
00001988: PUSH2 0x0776
0000198b: SWAP1
0000198c: PUSH2 0x2783
0000198f: JUMP
00001990: JUMPDEST
00001991: PUSH1 0x00
00001993: DUP1
00001994: SLOAD
00001995: PUSH1 0xff
00001997: NOT
00001998: AND
00001999: PUSH1 0x01
0000199b: OR
0000199c: SWAP1
0000199d: SSTORE
0000199e: DUP1
0000199f: ISZERO
000019a0: PUSH2 0x19b3
000019a3: JUMPI
000019a4: PUSH1 0x00
000019a6: DUP1
000019a7: SLOAD
000019a8: PUSH2 0xff00
000019ab: NOT
000019ac: AND
000019ad: PUSH2 0x0100
000019b0: OR
000019b1: SWAP1
000019b2: SSTORE
000019b3: JUMPDEST
000019b4: PUSH2 0x19bb
000019b7: PUSH2 0x1e79
000019ba: JUMP
000019bb: JUMPDEST
000019bc: PUSH2 0x19c6
000019bf: PUSH1 0x00
000019c1: CALLER
000019c2: PUSH2 0x1e6f
000019c5: JUMP
000019c6: JUMPDEST
000019c7: PUSH1 0xc9
000019c9: DUP1
000019ca: SLOAD
000019cb: PUSH1 0x01
000019cd: PUSH1 0x01
000019cf: PUSH1 0xa0
000019d1: SHL
000019d2: SUB
000019d3: NOT
000019d4: AND
000019d5: PUSH1 0x01
000019d7: PUSH1 0x01
000019d9: PUSH1 0xa0
000019db: SHL
000019dc: SUB
000019dd: DUP5
000019de: AND
000019df: OR
000019e0: SWAP1
000019e1: SSTORE
000019e2: DUP1
000019e3: ISZERO
000019e4: PUSH2 0x0c9e
000019e7: JUMPI
000019e8: PUSH1 0x00
000019ea: DUP1
000019eb: SLOAD
000019ec: PUSH2 0xff00
000019ef: NOT
000019f0: AND
000019f1: SWAP1
000019f2: SSTORE
000019f3: PUSH1 0x40
000019f5: MLOAD
000019f6: PUSH1 0x01
000019f8: DUP2
000019f9: MSTORE
000019fa: PUSH32 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498
00001a1b: SWAP1
00001a1c: PUSH1 0x20
00001a1e: ADD
00001a1f: PUSH1 0x40
00001a21: MLOAD
00001a22: DUP1
00001a23: SWAP2
00001a24: SUB
00001a25: SWAP1
00001a26: LOG1
00001a27: POP
00001a28: POP
00001a29: JUMP
00001a2a: JUMPDEST
00001a2b: PUSH1 0x00
00001a2d: DUP2
00001a2e: DUP2
00001a2f: MSTORE
00001a30: PUSH1 0x97
00001a32: PUSH1 0x20
00001a34: MSTORE
00001a35: PUSH1 0x40
00001a37: DUP2
00001a38: KECCAK256
00001a39: PUSH2 0x0717
00001a3c: SWAP1
00001a3d: PUSH2 0x1ee6
00001a40: JUMP
00001a41: JUMPDEST
00001a42: PUSH1 0x00
00001a44: DUP3
00001a45: DUP2
00001a46: MSTORE
00001a47: PUSH1 0x65
00001a49: PUSH1 0x20
00001a4b: MSTORE
00001a4c: PUSH1 0x40
00001a4e: SWAP1
00001a4f: KECCAK256
00001a50: PUSH1 0x01
00001a52: ADD
00001a53: SLOAD
00001a54: PUSH2 0x1a5c
00001a57: DUP2
00001a58: PUSH2 0x1cbd
00001a5b: JUMP
00001a5c: JUMPDEST
00001a5d: PUSH2 0x0b0e
00001a60: DUP4
00001a61: DUP4
00001a62: PUSH2 0x1cec
00001a65: JUMP
00001a66: JUMPDEST
00001a67: PUSH1 0x00
00001a69: PUSH2 0x1aa7
00001a6c: DUP5
00001a6d: DUP5
00001a6e: DUP1
00001a6f: DUP1
00001a70: PUSH1 0x1f
00001a72: ADD
00001a73: PUSH1 0x20
00001a75: DUP1
00001a76: SWAP2
00001a77: DIV
00001a78: MUL
00001a79: PUSH1 0x20
00001a7b: ADD
00001a7c: PUSH1 0x40
00001a7e: MLOAD
00001a7f: SWAP1
00001a80: DUP2
00001a81: ADD
00001a82: PUSH1 0x40
00001a84: MSTORE
00001a85: DUP1
00001a86: SWAP4
00001a87: SWAP3
00001a88: SWAP2
00001a89: SWAP1
00001a8a: DUP2
00001a8b: DUP2
00001a8c: MSTORE
00001a8d: PUSH1 0x20
00001a8f: ADD
00001a90: DUP4
00001a91: DUP4
00001a92: DUP1
00001a93: DUP3
00001a94: DUP5
00001a95: CALLDATACOPY
00001a96: PUSH1 0x00
00001a98: SWAP3
00001a99: ADD
00001a9a: SWAP2
00001a9b: SWAP1
00001a9c: SWAP2
00001a9d: MSTORE
00001a9e: POP
00001a9f: PUSH2 0x1c45
00001aa2: SWAP3
00001aa3: POP
00001aa4: POP
00001aa5: POP
00001aa6: JUMP
00001aa7: JUMPDEST
00001aa8: SWAP1
00001aa9: POP
00001aaa: PUSH2 0x1ab4
00001aad: DUP2
00001aae: DUP4
00001aaf: CALLVALUE
00001ab0: PUSH2 0x1c75
00001ab3: JUMP
00001ab4: JUMPDEST
00001ab5: PUSH2 0x1b00
00001ab8: JUMPI
00001ab9: PUSH1 0x40
00001abb: MLOAD
00001abc: PUSH3 0x461bcd
00001ac0: PUSH1 0xe5
00001ac2: SHL
00001ac3: DUP2
00001ac4: MSTORE
00001ac5: PUSH1 0x20
00001ac7: PUSH1 0x04
00001ac9: DUP3
00001aca: ADD
00001acb: MSTORE
00001acc: PUSH1 0x1e
00001ace: PUSH1 0x24
00001ad0: DUP3
00001ad1: ADD
00001ad2: MSTORE
00001ad3: PUSH32 0x4e6f7420656e6f7567682045544820666f72207472616e73616374696f6e0000
00001af4: PUSH1 0x44
00001af6: DUP3
00001af7: ADD
00001af8: MSTORE
00001af9: PUSH1 0x64
00001afb: ADD
00001afc: PUSH2 0x0776
00001aff: JUMP
00001b00: JUMPDEST
00001b01: PUSH1 0x01
00001b03: PUSH1 0x01
00001b05: PUSH1 0xa0
00001b07: SHL
00001b08: SUB
00001b09: DUP3
00001b0a: AND
00001b0b: PUSH1 0x00
00001b0d: SWAP1
00001b0e: DUP2
00001b0f: MSTORE
00001b10: PUSH1 0xcc
00001b12: PUSH1 0x20
00001b14: SWAP1
00001b15: DUP2
00001b16: MSTORE
00001b17: PUSH1 0x40
00001b19: DUP1
00001b1a: DUP4
00001b1b: KECCAK256
00001b1c: DUP5
00001b1d: DUP5
00001b1e: MSTORE
00001b1f: SWAP1
00001b20: SWAP2
00001b21: MSTORE
00001b22: SWAP1
00001b23: KECCAK256
00001b24: SLOAD
00001b25: PUSH2 0x1b2f
00001b28: SWAP1
00001b29: CALLVALUE
00001b2a: SWAP1
00001b2b: PUSH2 0x28b6
00001b2e: JUMP
00001b2f: JUMPDEST
00001b30: PUSH1 0x01
00001b32: PUSH1 0x01
00001b34: PUSH1 0xa0
00001b36: SHL
00001b37: SUB
00001b38: DUP4
00001b39: AND
00001b3a: PUSH1 0x00
00001b3c: DUP2
00001b3d: DUP2
00001b3e: MSTORE
00001b3f: PUSH1 0xcc
00001b41: PUSH1 0x20
00001b43: SWAP1
00001b44: DUP2
00001b45: MSTORE
00001b46: PUSH1 0x40
00001b48: DUP1
00001b49: DUP4
00001b4a: KECCAK256
00001b4b: DUP7
00001b4c: DUP5
00001b4d: MSTORE
00001b4e: DUP3
00001b4f: MSTORE
00001b50: DUP1
00001b51: DUP4
00001b52: KECCAK256
00001b53: SWAP5
00001b54: SWAP1
00001b55: SWAP5
00001b56: SSTORE
00001b57: SWAP2
00001b58: DUP2
00001b59: MSTORE
00001b5a: PUSH1 0xcd
00001b5c: DUP3
00001b5d: MSTORE
00001b5e: DUP3
00001b5f: DUP2
00001b60: KECCAK256
00001b61: DUP5
00001b62: DUP3
00001b63: MSTORE
00001b64: SWAP1
00001b65: SWAP2
00001b66: MSTORE
00001b67: KECCAK256
00001b68: SLOAD
00001b69: PUSH1 0xff
00001b6b: AND
00001b6c: PUSH2 0x1701
00001b6f: JUMPI
00001b70: PUSH1 0x01
00001b72: PUSH1 0x01
00001b74: PUSH1 0xa0
00001b76: SHL
00001b77: SUB
00001b78: DUP1
00001b79: DUP4
00001b7a: AND
00001b7b: PUSH1 0x00
00001b7d: SWAP1
00001b7e: DUP2
00001b7f: MSTORE
00001b80: PUSH1 0xcd
00001b82: PUSH1 0x20
00001b84: SWAP1
00001b85: DUP2
00001b86: MSTORE
00001b87: PUSH1 0x40
00001b89: DUP1
00001b8a: DUP4
00001b8b: KECCAK256
00001b8c: DUP6
00001b8d: DUP5
00001b8e: MSTORE
00001b8f: SWAP1
00001b90: SWAP2
00001b91: MSTORE
00001b92: SWAP1
00001b93: KECCAK256
00001b94: DUP1
00001b95: SLOAD
00001b96: PUSH1 0xff
00001b98: NOT
00001b99: AND
00001b9a: PUSH1 0x01
00001b9c: OR
00001b9d: SWAP1
00001b9e: SSTORE
00001b9f: PUSH1 0xca
00001ba1: SLOAD
00001ba2: AND
00001ba3: PUSH4 0x94489202
00001ba8: DUP3
00001ba9: PUSH2 0x1bb1
00001bac: DUP2
00001bad: PUSH2 0x13b5
00001bb0: JUMP
00001bb1: JUMPDEST
00001bb2: PUSH2 0x1bba
00001bb5: DUP7
00001bb6: PUSH2 0x1ef0
00001bb9: JUMP
00001bba: JUMPDEST
00001bbb: PUSH1 0x40
00001bbd: MLOAD
00001bbe: DUP5
00001bbf: PUSH4 0xffffffff
00001bc4: AND
00001bc5: PUSH1 0xe0
00001bc7: SHL
00001bc8: DUP2
00001bc9: MSTORE
00001bca: PUSH1 0x04
00001bcc: ADD
00001bcd: PUSH2 0x1bd8
00001bd0: SWAP4
00001bd1: SWAP3
00001bd2: SWAP2
00001bd3: SWAP1
00001bd4: PUSH2 0x2861
00001bd7: JUMP
00001bd8: JUMPDEST
00001bd9: PUSH1 0x00
00001bdb: PUSH1 0x40
00001bdd: MLOAD
00001bde: DUP1
00001bdf: DUP4
00001be0: SUB
00001be1: DUP2
00001be2: PUSH1 0x00
00001be4: DUP8
00001be5: DUP1
00001be6: EXTCODESIZE
00001be7: ISZERO
00001be8: DUP1
00001be9: ISZERO
00001bea: PUSH2 0x1bf2
00001bed: JUMPI
00001bee: PUSH1 0x00
00001bf0: DUP1
00001bf1: REVERT
00001bf2: JUMPDEST
00001bf3: POP
00001bf4: GAS
00001bf5: CALL
00001bf6: ISZERO
00001bf7: DUP1
00001bf8: ISZERO
00001bf9: PUSH2 0x1c06
00001bfc: JUMPI
00001bfd: RETURNDATASIZE
00001bfe: PUSH1 0x00
00001c00: DUP1
00001c01: RETURNDATACOPY
00001c02: RETURNDATASIZE
00001c03: PUSH1 0x00
00001c05: REVERT
00001c06: JUMPDEST
00001c07: POP
00001c08: POP
00001c09: POP
00001c0a: POP
00001c0b: POP
00001c0c: POP
00001c0d: POP
00001c0e: POP
00001c0f: JUMP
00001c10: JUMPDEST
00001c11: PUSH1 0x00
00001c13: PUSH1 0x01
00001c15: PUSH1 0x01
00001c17: PUSH1 0xe0
00001c19: SHL
00001c1a: SUB
00001c1b: NOT
00001c1c: DUP3
00001c1d: AND
00001c1e: PUSH4 0x7965db0b
00001c23: PUSH1 0xe0
00001c25: SHL
00001c26: EQ
00001c27: DUP1
00001c28: PUSH2 0x0717
00001c2b: JUMPI
00001c2c: POP
00001c2d: PUSH4 0x01ffc9a7
00001c32: PUSH1 0xe0
00001c34: SHL
00001c35: PUSH1 0x01
00001c37: PUSH1 0x01
00001c39: PUSH1 0xe0
00001c3b: SHL
00001c3c: SUB
00001c3d: NOT
00001c3e: DUP4
00001c3f: AND
00001c40: EQ
00001c41: PUSH2 0x0717
00001c44: JUMP
00001c45: JUMPDEST
00001c46: PUSH1 0x00
00001c48: DUP2
00001c49: PUSH1 0x40
00001c4b: MLOAD
00001c4c: PUSH1 0x20
00001c4e: ADD
00001c4f: PUSH2 0x1c58
00001c52: SWAP2
00001c53: SWAP1
00001c54: PUSH2 0x28c9
00001c57: JUMP
00001c58: JUMPDEST
00001c59: PUSH1 0x40
00001c5b: MLOAD
00001c5c: PUSH1 0x20
00001c5e: DUP2
00001c5f: DUP4
00001c60: SUB
00001c61: SUB
00001c62: DUP2
00001c63: MSTORE
00001c64: SWAP1
00001c65: PUSH1 0x40
00001c67: MSTORE
00001c68: DUP1
00001c69: MLOAD
00001c6a: SWAP1
00001c6b: PUSH1 0x20
00001c6d: ADD
00001c6e: KECCAK256
00001c6f: SWAP1
00001c70: POP
00001c71: SWAP2
00001c72: SWAP1
00001c73: POP
00001c74: JUMP
00001c75: JUMPDEST
00001c76: PUSH1 0x00
00001c78: GASPRICE
00001c79: PUSH1 0xce
00001c7b: SLOAD
00001c7c: PUSH2 0x1c85
00001c7f: SWAP2
00001c80: SWAP1
00001c81: PUSH2 0x27e7
00001c84: JUMP
00001c85: JUMPDEST
00001c86: PUSH1 0x01
00001c88: PUSH1 0x01
00001c8a: PUSH1 0xa0
00001c8c: SHL
00001c8d: SUB
00001c8e: DUP5
00001c8f: AND
00001c90: PUSH1 0x00
00001c92: SWAP1
00001c93: DUP2
00001c94: MSTORE
00001c95: PUSH1 0xcc
00001c97: PUSH1 0x20
00001c99: SWAP1
00001c9a: DUP2
00001c9b: MSTORE
00001c9c: PUSH1 0x40
00001c9e: DUP1
00001c9f: DUP4
00001ca0: KECCAK256
00001ca1: DUP9
00001ca2: DUP5
00001ca3: MSTORE
00001ca4: SWAP1
00001ca5: SWAP2
00001ca6: MSTORE
00001ca7: SWAP1
00001ca8: KECCAK256
00001ca9: SLOAD
00001caa: PUSH2 0x1cb3
00001cad: SWAP1
00001cae: DUP5
00001caf: PUSH2 0x28b6
00001cb2: JUMP
00001cb3: JUMPDEST
00001cb4: LT
00001cb5: ISZERO
00001cb6: SWAP5
00001cb7: SWAP4
00001cb8: POP
00001cb9: POP
00001cba: POP
00001cbb: POP
00001cbc: JUMP
00001cbd: JUMPDEST
00001cbe: PUSH2 0x1cc7
00001cc1: DUP2
00001cc2: CALLER
00001cc3: PUSH2 0x1efd
00001cc6: JUMP
00001cc7: JUMPDEST
00001cc8: POP
00001cc9: JUMP
00001cca: JUMPDEST
00001ccb: PUSH2 0x1cd4
00001cce: DUP3
00001ccf: DUP3
00001cd0: PUSH2 0x1f56
00001cd3: JUMP
00001cd4: JUMPDEST
00001cd5: PUSH1 0x00
00001cd7: DUP3
00001cd8: DUP2
00001cd9: MSTORE
00001cda: PUSH1 0x97
00001cdc: PUSH1 0x20
00001cde: MSTORE
00001cdf: PUSH1 0x40
00001ce1: SWAP1
00001ce2: KECCAK256
00001ce3: PUSH2 0x0b0e
00001ce6: SWAP1
00001ce7: DUP3
00001ce8: PUSH2 0x1fdc
00001ceb: JUMP
00001cec: JUMPDEST
00001ced: PUSH2 0x1cf6
00001cf0: DUP3
00001cf1: DUP3
00001cf2: PUSH2 0x1ff1
00001cf5: JUMP
00001cf6: JUMPDEST
00001cf7: PUSH1 0x00
00001cf9: DUP3
00001cfa: DUP2
00001cfb: MSTORE
00001cfc: PUSH1 0x97
00001cfe: PUSH1 0x20
00001d00: MSTORE
00001d01: PUSH1 0x40
00001d03: SWAP1
00001d04: KECCAK256
00001d05: PUSH2 0x0b0e
00001d08: SWAP1
00001d09: DUP3
00001d0a: PUSH2 0x2058
00001d0d: JUMP
00001d0e: JUMPDEST
00001d0f: PUSH1 0x60
00001d11: PUSH2 0x0717
00001d14: DUP3
00001d15: PUSH1 0x00
00001d17: PUSH2 0x206d
00001d1a: JUMP
00001d1b: JUMPDEST
00001d1c: DUP1
00001d1d: SELFBALANCE
00001d1e: LT
00001d1f: ISZERO
00001d20: PUSH2 0x1d6b
00001d23: JUMPI
00001d24: PUSH1 0x40
00001d26: MLOAD
00001d27: PUSH3 0x461bcd
00001d2b: PUSH1 0xe5
00001d2d: SHL
00001d2e: DUP2
00001d2f: MSTORE
00001d30: PUSH1 0x20
00001d32: PUSH1 0x04
00001d34: DUP3
00001d35: ADD
00001d36: MSTORE
00001d37: PUSH1 0x1d
00001d39: PUSH1 0x24
00001d3b: DUP3
00001d3c: ADD
00001d3d: MSTORE
00001d3e: PUSH32 0x416464726573733a20696e73756666696369656e742062616c616e6365000000
00001d5f: PUSH1 0x44
00001d61: DUP3
00001d62: ADD
00001d63: MSTORE
00001d64: PUSH1 0x64
00001d66: ADD
00001d67: PUSH2 0x0776
00001d6a: JUMP
00001d6b: JUMPDEST
00001d6c: PUSH1 0x00
00001d6e: DUP3
00001d6f: PUSH1 0x01
00001d71: PUSH1 0x01
00001d73: PUSH1 0xa0
00001d75: SHL
00001d76: SUB
00001d77: AND
00001d78: DUP3
00001d79: PUSH1 0x40
00001d7b: MLOAD
00001d7c: PUSH1 0x00
00001d7e: PUSH1 0x40
00001d80: MLOAD
00001d81: DUP1
00001d82: DUP4
00001d83: SUB
00001d84: DUP2
00001d85: DUP6
00001d86: DUP8
00001d87: GAS
00001d88: CALL
00001d89: SWAP3
00001d8a: POP
00001d8b: POP
00001d8c: POP
00001d8d: RETURNDATASIZE
00001d8e: DUP1
00001d8f: PUSH1 0x00
00001d91: DUP2
00001d92: EQ
00001d93: PUSH2 0x1db8
00001d96: JUMPI
00001d97: PUSH1 0x40
00001d99: MLOAD
00001d9a: SWAP2
00001d9b: POP
00001d9c: PUSH1 0x1f
00001d9e: NOT
00001d9f: PUSH1 0x3f
00001da1: RETURNDATASIZE
00001da2: ADD
00001da3: AND
00001da4: DUP3
00001da5: ADD
00001da6: PUSH1 0x40
00001da8: MSTORE
00001da9: RETURNDATASIZE
00001daa: DUP3
00001dab: MSTORE
00001dac: RETURNDATASIZE
00001dad: PUSH1 0x00
00001daf: PUSH1 0x20
00001db1: DUP5
00001db2: ADD
00001db3: RETURNDATACOPY
00001db4: PUSH2 0x1dbd
00001db7: JUMP
00001db8: JUMPDEST
00001db9: PUSH1 0x60
00001dbb: SWAP2
00001dbc: POP
00001dbd: JUMPDEST
00001dbe: POP
00001dbf: POP
00001dc0: SWAP1
00001dc1: POP
00001dc2: DUP1
00001dc3: PUSH2 0x0b0e
00001dc6: JUMPI
00001dc7: PUSH1 0x40
00001dc9: MLOAD
00001dca: PUSH3 0x461bcd
00001dce: PUSH1 0xe5
00001dd0: SHL
00001dd1: DUP2
00001dd2: MSTORE
00001dd3: PUSH1 0x20
00001dd5: PUSH1 0x04
00001dd7: DUP3
00001dd8: ADD
00001dd9: MSTORE
00001dda: PUSH1 0x3a
00001ddc: PUSH1 0x24
00001dde: DUP3
00001ddf: ADD
00001de0: MSTORE
00001de1: PUSH32 0x416464726573733a20756e61626c6520746f2073656e642076616c75652c2072
00001e02: PUSH1 0x44
00001e04: DUP3
00001e05: ADD
00001e06: MSTORE
00001e07: PUSH32 0x6563697069656e74206d61792068617665207265766572746564000000000000
00001e28: PUSH1 0x64
00001e2a: DUP3
00001e2b: ADD
00001e2c: MSTORE
00001e2d: PUSH1 0x84
00001e2f: ADD
00001e30: PUSH2 0x0776
00001e33: JUMP
00001e34: JUMPDEST
00001e35: PUSH1 0x00
00001e37: PUSH1 0xd0
00001e39: SLOAD
00001e3a: PUSH1 0xcf
00001e3c: SLOAD
00001e3d: GASPRICE
00001e3e: PUSH1 0xce
00001e40: SLOAD
00001e41: PUSH2 0x1e4a
00001e44: SWAP2
00001e45: SWAP1
00001e46: PUSH2 0x27e7
00001e49: JUMP
00001e4a: JUMPDEST
00001e4b: PUSH2 0x1e54
00001e4e: SWAP2
00001e4f: SWAP1
00001e50: PUSH2 0x27e7
00001e53: JUMP
00001e54: JUMPDEST
00001e55: PUSH2 0x1e5e
00001e58: SWAP2
00001e59: SWAP1
00001e5a: PUSH2 0x2894
00001e5d: JUMP
00001e5e: JUMPDEST
00001e5f: SWAP1
00001e60: POP
00001e61: SWAP1
00001e62: JUMP
00001e63: JUMPDEST
00001e64: PUSH1 0x00
00001e66: PUSH2 0x0ae2
00001e69: DUP4
00001e6a: DUP4
00001e6b: PUSH2 0x20c6
00001e6e: JUMP
00001e6f: JUMPDEST
00001e70: PUSH2 0x0c9e
00001e73: DUP3
00001e74: DUP3
00001e75: PUSH2 0x1cca
00001e78: JUMP
00001e79: JUMPDEST
00001e7a: PUSH1 0x00
00001e7c: SLOAD
00001e7d: PUSH2 0x0100
00001e80: SWAP1
00001e81: DIV
00001e82: PUSH1 0xff
00001e84: AND
00001e85: PUSH2 0x1ee4
00001e88: JUMPI
00001e89: PUSH1 0x40
00001e8b: MLOAD
00001e8c: PUSH3 0x461bcd
00001e90: PUSH1 0xe5
00001e92: SHL
00001e93: DUP2
00001e94: MSTORE
00001e95: PUSH1 0x20
00001e97: PUSH1 0x04
00001e99: DUP3
00001e9a: ADD
00001e9b: MSTORE
00001e9c: PUSH1 0x2b
00001e9e: PUSH1 0x24
00001ea0: DUP3
00001ea1: ADD
00001ea2: MSTORE
00001ea3: PUSH32 0x496e697469616c697a61626c653a20636f6e7472616374206973206e6f742069
00001ec4: PUSH1 0x44
00001ec6: DUP3
00001ec7: ADD
00001ec8: MSTORE
00001ec9: PUSH11 0x6e697469616c697a696e67
00001ed5: PUSH1 0xa8
00001ed7: SHL
00001ed8: PUSH1 0x64
00001eda: DUP3
00001edb: ADD
00001edc: MSTORE
00001edd: PUSH1 0x84
00001edf: ADD
00001ee0: PUSH2 0x0776
00001ee3: JUMP
00001ee4: JUMPDEST
00001ee5: JUMP
00001ee6: JUMPDEST
00001ee7: PUSH1 0x00
00001ee9: PUSH2 0x0717
00001eec: DUP3
00001eed: SLOAD
00001eee: SWAP1
00001eef: JUMP
00001ef0: JUMPDEST
00001ef1: PUSH1 0x60
00001ef3: PUSH2 0x0717
00001ef6: DUP3
00001ef7: PUSH1 0x01
00001ef9: PUSH2 0x206d
00001efc: JUMP
00001efd: JUMPDEST
00001efe: PUSH2 0x1f07
00001f01: DUP3
00001f02: DUP3
00001f03: PUSH2 0x1459
00001f06: JUMP
00001f07: JUMPDEST
00001f08: PUSH2 0x0c9e
00001f0b: JUMPI
00001f0c: PUSH2 0x1f14
00001f0f: DUP2
00001f10: PUSH2 0x20f0
00001f13: JUMP
00001f14: JUMPDEST
00001f15: PUSH2 0x1f1f
00001f18: DUP4
00001f19: PUSH1 0x20
00001f1b: PUSH2 0x2102
00001f1e: JUMP
00001f1f: JUMPDEST
00001f20: PUSH1 0x40
00001f22: MLOAD
00001f23: PUSH1 0x20
00001f25: ADD
00001f26: PUSH2 0x1f30
00001f29: SWAP3
00001f2a: SWAP2
00001f2b: SWAP1
00001f2c: PUSH2 0x28e5
00001f2f: JUMP
00001f30: JUMPDEST
00001f31: PUSH1 0x40
00001f33: DUP1
00001f34: MLOAD
00001f35: PUSH1 0x1f
00001f37: NOT
00001f38: DUP2
00001f39: DUP5
00001f3a: SUB
00001f3b: ADD
00001f3c: DUP2
00001f3d: MSTORE
00001f3e: SWAP1
00001f3f: DUP3
00001f40: SWAP1
00001f41: MSTORE
00001f42: PUSH3 0x461bcd
00001f46: PUSH1 0xe5
00001f48: SHL
00001f49: DUP3
00001f4a: MSTORE
00001f4b: PUSH2 0x0776
00001f4e: SWAP2
00001f4f: PUSH1 0x04
00001f51: ADD
00001f52: PUSH2 0x295a
00001f55: JUMP
00001f56: JUMPDEST
00001f57: PUSH2 0x1f60
00001f5a: DUP3
00001f5b: DUP3
00001f5c: PUSH2 0x1459
00001f5f: JUMP
00001f60: JUMPDEST
00001f61: PUSH2 0x0c9e
00001f64: JUMPI
00001f65: PUSH1 0x00
00001f67: DUP3
00001f68: DUP2
00001f69: MSTORE
00001f6a: PUSH1 0x65
00001f6c: PUSH1 0x20
00001f6e: SWAP1
00001f6f: DUP2
00001f70: MSTORE
00001f71: PUSH1 0x40
00001f73: DUP1
00001f74: DUP4
00001f75: KECCAK256
00001f76: PUSH1 0x01
00001f78: PUSH1 0x01
00001f7a: PUSH1 0xa0
00001f7c: SHL
00001f7d: SUB
00001f7e: DUP6
00001f7f: AND
00001f80: DUP5
00001f81: MSTORE
00001f82: SWAP1
00001f83: SWAP2
00001f84: MSTORE
00001f85: SWAP1
00001f86: KECCAK256
00001f87: DUP1
00001f88: SLOAD
00001f89: PUSH1 0xff
00001f8b: NOT
00001f8c: AND
00001f8d: PUSH1 0x01
00001f8f: OR
00001f90: SWAP1
00001f91: SSTORE
00001f92: PUSH2 0x1f98
00001f95: CALLER
00001f96: SWAP1
00001f97: JUMP
00001f98: JUMPDEST
00001f99: PUSH1 0x01
00001f9b: PUSH1 0x01
00001f9d: PUSH1 0xa0
00001f9f: SHL
00001fa0: SUB
00001fa1: AND
00001fa2: DUP2
00001fa3: PUSH1 0x01
00001fa5: PUSH1 0x01
00001fa7: PUSH1 0xa0
00001fa9: SHL
00001faa: SUB
00001fab: AND
00001fac: DUP4
00001fad: PUSH32 0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d
00001fce: PUSH1 0x40
00001fd0: MLOAD
00001fd1: PUSH1 0x40
00001fd3: MLOAD
00001fd4: DUP1
00001fd5: SWAP2
00001fd6: SUB
00001fd7: SWAP1
00001fd8: LOG4
00001fd9: POP
00001fda: POP
00001fdb: JUMP
00001fdc: JUMPDEST
00001fdd: PUSH1 0x00
00001fdf: PUSH2 0x0ae2
00001fe2: DUP4
00001fe3: PUSH1 0x01
00001fe5: PUSH1 0x01
00001fe7: PUSH1 0xa0
00001fe9: SHL
00001fea: SUB
00001feb: DUP5
00001fec: AND
00001fed: PUSH2 0x229e
00001ff0: JUMP
00001ff1: JUMPDEST
00001ff2: PUSH2 0x1ffb
00001ff5: DUP3
00001ff6: DUP3
00001ff7: PUSH2 0x1459
00001ffa: JUMP
00001ffb: JUMPDEST
00001ffc: ISZERO
00001ffd: PUSH2 0x0c9e
00002000: JUMPI
00002001: PUSH1 0x00
00002003: DUP3
00002004: DUP2
00002005: MSTORE
00002006: PUSH1 0x65
00002008: PUSH1 0x20
0000200a: SWAP1
0000200b: DUP2
0000200c: MSTORE
0000200d: PUSH1 0x40
0000200f: DUP1
00002010: DUP4
00002011: KECCAK256
00002012: PUSH1 0x01
00002014: PUSH1 0x01
00002016: PUSH1 0xa0
00002018: SHL
00002019: SUB
0000201a: DUP6
0000201b: AND
0000201c: DUP1
0000201d: DUP6
0000201e: MSTORE
0000201f: SWAP3
00002020: MSTORE
00002021: DUP1
00002022: DUP4
00002023: KECCAK256
00002024: DUP1
00002025: SLOAD
00002026: PUSH1 0xff
00002028: NOT
00002029: AND
0000202a: SWAP1
0000202b: SSTORE
0000202c: MLOAD
0000202d: CALLER
0000202e: SWAP3
0000202f: DUP6
00002030: SWAP2
00002031: PUSH32 0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b
00002052: SWAP2
00002053: SWAP1
00002054: LOG4
00002055: POP
00002056: POP
00002057: JUMP
00002058: JUMPDEST
00002059: PUSH1 0x00
0000205b: PUSH2 0x0ae2
0000205e: DUP4
0000205f: PUSH1 0x01
00002061: PUSH1 0x01
00002063: PUSH1 0xa0
00002065: SHL
00002066: SUB
00002067: DUP5
00002068: AND
00002069: PUSH2 0x22ed
0000206c: JUMP
0000206d: JUMPDEST
0000206e: PUSH1 0x40
00002070: DUP1
00002071: MLOAD
00002072: PUSH1 0x80
00002074: DUP2
00002075: ADD
00002076: DUP3
00002077: MSTORE
00002078: PUSH1 0x07
0000207a: PUSH1 0x60
0000207c: DUP1
0000207d: DUP4
0000207e: ADD
0000207f: SWAP2
00002080: DUP3
00002081: MSTORE
00002082: SWAP1
00002083: DUP3
00002084: MSTORE
00002085: PUSH1 0x01
00002087: PUSH1 0x01
00002089: PUSH1 0xa0
0000208b: SHL
0000208c: SUB
0000208d: DUP6
0000208e: AND
0000208f: PUSH1 0x20
00002091: DUP1
00002092: DUP5
00002093: ADD
00002094: SWAP2
00002095: SWAP1
00002096: SWAP2
00002097: MSTORE
00002098: DUP5
00002099: ISZERO
0000209a: ISZERO
0000209b: DUP4
0000209c: DUP6
0000209d: ADD
0000209e: MSTORE
0000209f: SWAP3
000020a0: MLOAD
000020a1: SWAP1
000020a2: SWAP3
000020a3: PUSH2 0x20ae
000020a6: SWAP2
000020a7: DUP4
000020a8: SWAP2
000020a9: ADD
000020aa: PUSH2 0x296d
000020ad: JUMP
000020ae: JUMPDEST
000020af: PUSH1 0x40
000020b1: MLOAD
000020b2: PUSH1 0x20
000020b4: DUP2
000020b5: DUP4
000020b6: SUB
000020b7: SUB
000020b8: DUP2
000020b9: MSTORE
000020ba: SWAP1
000020bb: PUSH1 0x40
000020bd: MSTORE
000020be: SWAP2
000020bf: POP
000020c0: POP
000020c1: SWAP3
000020c2: SWAP2
000020c3: POP
000020c4: POP
000020c5: JUMP
000020c6: JUMPDEST
000020c7: PUSH1 0x00
000020c9: DUP3
000020ca: PUSH1 0x00
000020cc: ADD
000020cd: DUP3
000020ce: DUP2
000020cf: SLOAD
000020d0: DUP2
000020d1: LT
000020d2: PUSH2 0x20dd
000020d5: JUMPI
000020d6: PUSH2 0x20dd
000020d9: PUSH2 0x29bb
000020dc: JUMP
000020dd: JUMPDEST
000020de: SWAP1
000020df: PUSH1 0x00
000020e1: MSTORE
000020e2: PUSH1 0x20
000020e4: PUSH1 0x00
000020e6: KECCAK256
000020e7: ADD
000020e8: SLOAD
000020e9: SWAP1
000020ea: POP
000020eb: SWAP3
000020ec: SWAP2
000020ed: POP
000020ee: POP
000020ef: JUMP
000020f0: JUMPDEST
000020f1: PUSH1 0x60
000020f3: PUSH2 0x0717
000020f6: PUSH1 0x01
000020f8: PUSH1 0x01
000020fa: PUSH1 0xa0
000020fc: SHL
000020fd: SUB
000020fe: DUP4
000020ff: AND
00002100: PUSH1 0x14
00002102: JUMPDEST
00002103: PUSH1 0x60
00002105: PUSH1 0x00
00002107: PUSH2 0x2111
0000210a: DUP4
0000210b: PUSH1 0x02
0000210d: PUSH2 0x27e7
00002110: JUMP
00002111: JUMPDEST
00002112: PUSH2 0x211c
00002115: SWAP1
00002116: PUSH1 0x02
00002118: PUSH2 0x28b6
0000211b: JUMP
0000211c: JUMPDEST
0000211d: PUSH8 0xffffffffffffffff
00002126: DUP2
00002127: GT
00002128: ISZERO
00002129: PUSH2 0x2134
0000212c: JUMPI
0000212d: PUSH2 0x2134
00002130: PUSH2 0x29d1
00002133: JUMP
00002134: JUMPDEST
00002135: PUSH1 0x40
00002137: MLOAD
00002138: SWAP1
00002139: DUP1
0000213a: DUP3
0000213b: MSTORE
0000213c: DUP1
0000213d: PUSH1 0x1f
0000213f: ADD
00002140: PUSH1 0x1f
00002142: NOT
00002143: AND
00002144: PUSH1 0x20
00002146: ADD
00002147: DUP3
00002148: ADD
00002149: PUSH1 0x40
0000214b: MSTORE
0000214c: DUP1
0000214d: ISZERO
0000214e: PUSH2 0x215e
00002151: JUMPI
00002152: PUSH1 0x20
00002154: DUP3
00002155: ADD
00002156: DUP2
00002157: DUP1
00002158: CALLDATASIZE
00002159: DUP4
0000215a: CALLDATACOPY
0000215b: ADD
0000215c: SWAP1
0000215d: POP
0000215e: JUMPDEST
0000215f: POP
00002160: SWAP1
00002161: POP
00002162: PUSH1 0x03
00002164: PUSH1 0xfc
00002166: SHL
00002167: DUP2
00002168: PUSH1 0x00
0000216a: DUP2
0000216b: MLOAD
0000216c: DUP2
0000216d: LT
0000216e: PUSH2 0x2179
00002171: JUMPI
00002172: PUSH2 0x2179
00002175: PUSH2 0x29bb
00002178: JUMP
00002179: JUMPDEST
0000217a: PUSH1 0x20
0000217c: ADD
0000217d: ADD
0000217e: SWAP1
0000217f: PUSH1 0x01
00002181: PUSH1 0x01
00002183: PUSH1 0xf8
00002185: SHL
00002186: SUB
00002187: NOT
00002188: AND
00002189: SWAP1
0000218a: DUP2
0000218b: PUSH1 0x00
0000218d: BYTE
0000218e: SWAP1
0000218f: MSTORE8
00002190: POP
00002191: PUSH1 0x0f
00002193: PUSH1 0xfb
00002195: SHL
00002196: DUP2
00002197: PUSH1 0x01
00002199: DUP2
0000219a: MLOAD
0000219b: DUP2
0000219c: LT
0000219d: PUSH2 0x21a8
000021a0: JUMPI
000021a1: PUSH2 0x21a8
000021a4: PUSH2 0x29bb
000021a7: JUMP
000021a8: JUMPDEST
000021a9: PUSH1 0x20
000021ab: ADD
000021ac: ADD
000021ad: SWAP1
000021ae: PUSH1 0x01
000021b0: PUSH1 0x01
000021b2: PUSH1 0xf8
000021b4: SHL
000021b5: SUB
000021b6: NOT
000021b7: AND
000021b8: SWAP1
000021b9: DUP2
000021ba: PUSH1 0x00
000021bc: BYTE
000021bd: SWAP1
000021be: MSTORE8
000021bf: POP
000021c0: PUSH1 0x00
000021c2: PUSH2 0x21cc
000021c5: DUP5
000021c6: PUSH1 0x02
000021c8: PUSH2 0x27e7
000021cb: JUMP
000021cc: JUMPDEST
000021cd: PUSH2 0x21d7
000021d0: SWAP1
000021d1: PUSH1 0x01
000021d3: PUSH2 0x28b6
000021d6: JUMP
000021d7: JUMPDEST
000021d8: SWAP1
000021d9: POP
000021da: JUMPDEST
000021db: PUSH1 0x01
000021dd: DUP2
000021de: GT
000021df: ISZERO
000021e0: PUSH2 0x224f
000021e3: JUMPI
000021e4: PUSH16 0x181899199a1a9b1b9c1cb0b131b232b3
000021f5: PUSH1 0x81
000021f7: SHL
000021f8: DUP6
000021f9: PUSH1 0x0f
000021fb: AND
000021fc: PUSH1 0x10
000021fe: DUP2
000021ff: LT
00002200: PUSH2 0x220b
00002203: JUMPI
00002204: PUSH2 0x220b
00002207: PUSH2 0x29bb
0000220a: JUMP
0000220b: JUMPDEST
0000220c: BYTE
0000220d: PUSH1 0xf8
0000220f: SHL
00002210: DUP3
00002211: DUP3
00002212: DUP2
00002213: MLOAD
00002214: DUP2
00002215: LT
00002216: PUSH2 0x2221
00002219: JUMPI
0000221a: PUSH2 0x2221
0000221d: PUSH2 0x29bb
00002220: JUMP
00002221: JUMPDEST
00002222: PUSH1 0x20
00002224: ADD
00002225: ADD
00002226: SWAP1
00002227: PUSH1 0x01
00002229: PUSH1 0x01
0000222b: PUSH1 0xf8
0000222d: SHL
0000222e: SUB
0000222f: NOT
00002230: AND
00002231: SWAP1
00002232: DUP2
00002233: PUSH1 0x00
00002235: BYTE
00002236: SWAP1
00002237: MSTORE8
00002238: POP
00002239: PUSH1 0x04
0000223b: SWAP5
0000223c: SWAP1
0000223d: SWAP5
0000223e: SHR
0000223f: SWAP4
00002240: PUSH2 0x2248
00002243: DUP2
00002244: PUSH2 0x29e7
00002247: JUMP
00002248: JUMPDEST
00002249: SWAP1
0000224a: POP
0000224b: PUSH2 0x21da
0000224e: JUMP
0000224f: JUMPDEST
00002250: POP
00002251: DUP4
00002252: ISZERO
00002253: PUSH2 0x0ae2
00002256: JUMPI
00002257: PUSH1 0x40
00002259: MLOAD
0000225a: PUSH3 0x461bcd
0000225e: PUSH1 0xe5
00002260: SHL
00002261: DUP2
00002262: MSTORE
00002263: PUSH1 0x20
00002265: PUSH1 0x04
00002267: DUP3
00002268: ADD
00002269: DUP2
0000226a: SWAP1
0000226b: MSTORE
0000226c: PUSH1 0x24
0000226e: DUP3
0000226f: ADD
00002270: MSTORE
00002271: PUSH32 0x537472696e67733a20686578206c656e67746820696e73756666696369656e74
00002292: PUSH1 0x44
00002294: DUP3
00002295: ADD
00002296: MSTORE
00002297: PUSH1 0x64
00002299: ADD
0000229a: PUSH2 0x0776
0000229d: JUMP
0000229e: JUMPDEST
0000229f: PUSH1 0x00
000022a1: DUP2
000022a2: DUP2
000022a3: MSTORE
000022a4: PUSH1 0x01
000022a6: DUP4
000022a7: ADD
000022a8: PUSH1 0x20
000022aa: MSTORE
000022ab: PUSH1 0x40
000022ad: DUP2
000022ae: KECCAK256
000022af: SLOAD
000022b0: PUSH2 0x22e5
000022b3: JUMPI
000022b4: POP
000022b5: DUP2
000022b6: SLOAD
000022b7: PUSH1 0x01
000022b9: DUP2
000022ba: DUP2
000022bb: ADD
000022bc: DUP5
000022bd: SSTORE
000022be: PUSH1 0x00
000022c0: DUP5
000022c1: DUP2
000022c2: MSTORE
000022c3: PUSH1 0x20
000022c5: DUP1
000022c6: DUP3
000022c7: KECCAK256
000022c8: SWAP1
000022c9: SWAP4
000022ca: ADD
000022cb: DUP5
000022cc: SWAP1
000022cd: SSTORE
000022ce: DUP5
000022cf: SLOAD
000022d0: DUP5
000022d1: DUP3
000022d2: MSTORE
000022d3: DUP3
000022d4: DUP7
000022d5: ADD
000022d6: SWAP1
000022d7: SWAP4
000022d8: MSTORE
000022d9: PUSH1 0x40
000022db: SWAP1
000022dc: KECCAK256
000022dd: SWAP2
000022de: SWAP1
000022df: SWAP2
000022e0: SSTORE
000022e1: PUSH2 0x0717
000022e4: JUMP
000022e5: JUMPDEST
000022e6: POP
000022e7: PUSH1 0x00
000022e9: PUSH2 0x0717
000022ec: JUMP
000022ed: JUMPDEST
000022ee: PUSH1 0x00
000022f0: DUP2
000022f1: DUP2
000022f2: MSTORE
000022f3: PUSH1 0x01
000022f5: DUP4
000022f6: ADD
000022f7: PUSH1 0x20
000022f9: MSTORE
000022fa: PUSH1 0x40
000022fc: DUP2
000022fd: KECCAK256
000022fe: SLOAD
000022ff: DUP1
00002300: ISZERO
00002301: PUSH2 0x23d6
00002304: JUMPI
00002305: PUSH1 0x00
00002307: PUSH2 0x2311
0000230a: PUSH1 0x01
0000230c: DUP4
0000230d: PUSH2 0x27fe
00002310: JUMP
00002311: JUMPDEST
00002312: DUP6
00002313: SLOAD
00002314: SWAP1
00002315: SWAP2
00002316: POP
00002317: PUSH1 0x00
00002319: SWAP1
0000231a: PUSH2 0x2325
0000231d: SWAP1
0000231e: PUSH1 0x01
00002320: SWAP1
00002321: PUSH2 0x27fe
00002324: JUMP
00002325: JUMPDEST
00002326: SWAP1
00002327: POP
00002328: DUP2
00002329: DUP2
0000232a: EQ
0000232b: PUSH2 0x238a
0000232e: JUMPI
0000232f: PUSH1 0x00
00002331: DUP7
00002332: PUSH1 0x00
00002334: ADD
00002335: DUP3
00002336: DUP2
00002337: SLOAD
00002338: DUP2
00002339: LT
0000233a: PUSH2 0x2345
0000233d: JUMPI
0000233e: PUSH2 0x2345
00002341: PUSH2 0x29bb
00002344: JUMP
00002345: JUMPDEST
00002346: SWAP1
00002347: PUSH1 0x00
00002349: MSTORE
0000234a: PUSH1 0x20
0000234c: PUSH1 0x00
0000234e: KECCAK256
0000234f: ADD
00002350: SLOAD
00002351: SWAP1
00002352: POP
00002353: DUP1
00002354: DUP8
00002355: PUSH1 0x00
00002357: ADD
00002358: DUP5
00002359: DUP2
0000235a: SLOAD
0000235b: DUP2
0000235c: LT
0000235d: PUSH2 0x2368
00002360: JUMPI
00002361: PUSH2 0x2368
00002364: PUSH2 0x29bb
00002367: JUMP
00002368: JUMPDEST
00002369: PUSH1 0x00
0000236b: SWAP2
0000236c: DUP3
0000236d: MSTORE
0000236e: PUSH1 0x20
00002370: DUP1
00002371: DUP4
00002372: KECCAK256
00002373: SWAP1
00002374: SWAP2
00002375: ADD
00002376: SWAP3
00002377: SWAP1
00002378: SWAP3
00002379: SSTORE
0000237a: SWAP2
0000237b: DUP3
0000237c: MSTORE
0000237d: PUSH1 0x01
0000237f: DUP9
00002380: ADD
00002381: SWAP1
00002382: MSTORE
00002383: PUSH1 0x40
00002385: SWAP1
00002386: KECCAK256
00002387: DUP4
00002388: SWAP1
00002389: SSTORE
0000238a: JUMPDEST
0000238b: DUP6
0000238c: SLOAD
0000238d: DUP7
0000238e: SWAP1
0000238f: DUP1
00002390: PUSH2 0x239b
00002393: JUMPI
00002394: PUSH2 0x239b
00002397: PUSH2 0x29fe
0000239a: JUMP
0000239b: JUMPDEST
0000239c: PUSH1 0x01
0000239e: SWAP1
0000239f: SUB
000023a0: DUP2
000023a1: DUP2
000023a2: SWAP1
000023a3: PUSH1 0x00
000023a5: MSTORE
000023a6: PUSH1 0x20
000023a8: PUSH1 0x00
000023aa: KECCAK256
000023ab: ADD
000023ac: PUSH1 0x00
000023ae: SWAP1
000023af: SSTORE
000023b0: SWAP1
000023b1: SSTORE
000023b2: DUP6
000023b3: PUSH1 0x01
000023b5: ADD
000023b6: PUSH1 0x00
000023b8: DUP7
000023b9: DUP2
000023ba: MSTORE
000023bb: PUSH1 0x20
000023bd: ADD
000023be: SWAP1
000023bf: DUP2
000023c0: MSTORE
000023c1: PUSH1 0x20
000023c3: ADD
000023c4: PUSH1 0x00
000023c6: KECCAK256
000023c7: PUSH1 0x00
000023c9: SWAP1
000023ca: SSTORE
000023cb: PUSH1 0x01
000023cd: SWAP4
000023ce: POP
000023cf: POP
000023d0: POP
000023d1: POP
000023d2: PUSH2 0x0717
000023d5: JUMP
000023d6: JUMPDEST
000023d7: PUSH1 0x00
000023d9: SWAP2
000023da: POP
000023db: POP
000023dc: PUSH2 0x0717
000023df: JUMP
000023e0: JUMPDEST
000023e1: PUSH1 0x00
000023e3: PUSH1 0x20
000023e5: DUP3
000023e6: DUP5
000023e7: SUB
000023e8: SLT
000023e9: ISZERO
000023ea: PUSH2 0x23f2
000023ed: JUMPI
000023ee: PUSH1 0x00
000023f0: DUP1
000023f1: REVERT
000023f2: JUMPDEST
000023f3: DUP2
000023f4: CALLDATALOAD
000023f5: PUSH1 0x01
000023f7: PUSH1 0x01
000023f9: PUSH1 0xe0
000023fb: SHL
000023fc: SUB
000023fd: NOT
000023fe: DUP2
000023ff: AND
00002400: DUP2
00002401: EQ
00002402: PUSH2 0x0ae2
00002405: JUMPI
00002406: PUSH1 0x00
00002408: DUP1
00002409: REVERT
0000240a: JUMPDEST
0000240b: PUSH1 0x01
0000240d: PUSH1 0x01
0000240f: PUSH1 0xa0
00002411: SHL
00002412: SUB
00002413: DUP2
00002414: AND
00002415: DUP2
00002416: EQ
00002417: PUSH2 0x1cc7
0000241a: JUMPI
0000241b: PUSH1 0x00
0000241d: DUP1
0000241e: REVERT
0000241f: JUMPDEST
00002420: PUSH1 0x00
00002422: DUP1
00002423: PUSH1 0x00
00002425: PUSH1 0x60
00002427: DUP5
00002428: DUP7
00002429: SUB
0000242a: SLT
0000242b: ISZERO
0000242c: PUSH2 0x2434
0000242f: JUMPI
00002430: PUSH1 0x00
00002432: DUP1
00002433: REVERT
00002434: JUMPDEST
00002435: DUP4
00002436: CALLDATALOAD
00002437: SWAP3
00002438: POP
00002439: PUSH1 0x20
0000243b: DUP5
0000243c: ADD
0000243d: CALLDATALOAD
0000243e: PUSH2 0x2446
00002441: DUP2
00002442: PUSH2 0x240a
00002445: JUMP
00002446: JUMPDEST
00002447: SWAP3
00002448: SWAP6
00002449: SWAP3
0000244a: SWAP5
0000244b: POP
0000244c: POP
0000244d: POP
0000244e: PUSH1 0x40
00002450: SWAP2
00002451: SWAP1
00002452: SWAP2
00002453: ADD
00002454: CALLDATALOAD
00002455: SWAP1
00002456: JUMP
00002457: JUMPDEST
00002458: PUSH1 0x00
0000245a: DUP1
0000245b: DUP4
0000245c: PUSH1 0x1f
0000245e: DUP5
0000245f: ADD
00002460: SLT
00002461: PUSH2 0x2469
00002464: JUMPI
00002465: PUSH1 0x00
00002467: DUP1
00002468: REVERT
00002469: JUMPDEST
0000246a: POP
0000246b: DUP2
0000246c: CALLDATALOAD
0000246d: PUSH8 0xffffffffffffffff
00002476: DUP2
00002477: GT
00002478: ISZERO
00002479: PUSH2 0x2481
0000247c: JUMPI
0000247d: PUSH1 0x00
0000247f: DUP1
00002480: REVERT
00002481: JUMPDEST
00002482: PUSH1 0x20
00002484: DUP4
00002485: ADD
00002486: SWAP2
00002487: POP
00002488: DUP4
00002489: PUSH1 0x20
0000248b: DUP3
0000248c: DUP6
0000248d: ADD
0000248e: ADD
0000248f: GT
00002490: ISZERO
00002491: PUSH2 0x2499
00002494: JUMPI
00002495: PUSH1 0x00
00002497: DUP1
00002498: REVERT
00002499: JUMPDEST
0000249a: SWAP3
0000249b: POP
0000249c: SWAP3
0000249d: SWAP1
0000249e: POP
0000249f: JUMP
000024a0: JUMPDEST
000024a1: PUSH1 0x00
000024a3: DUP1
000024a4: PUSH1 0x00
000024a6: PUSH1 0x40
000024a8: DUP5
000024a9: DUP7
000024aa: SUB
000024ab: SLT
000024ac: ISZERO
000024ad: PUSH2 0x24b5
000024b0: JUMPI
000024b1: PUSH1 0x00
000024b3: DUP1
000024b4: REVERT
000024b5: JUMPDEST
000024b6: DUP4
000024b7: CALLDATALOAD
000024b8: PUSH2 0x24c0
000024bb: DUP2
000024bc: PUSH2 0x240a
000024bf: JUMP
000024c0: JUMPDEST
000024c1: SWAP3
000024c2: POP
000024c3: PUSH1 0x20
000024c5: DUP5
000024c6: ADD
000024c7: CALLDATALOAD
000024c8: PUSH8 0xffffffffffffffff
000024d1: DUP2
000024d2: GT
000024d3: ISZERO
000024d4: PUSH2 0x24dc
000024d7: JUMPI
000024d8: PUSH1 0x00
000024da: DUP1
000024db: REVERT
000024dc: JUMPDEST
000024dd: PUSH2 0x24e8
000024e0: DUP7
000024e1: DUP3
000024e2: DUP8
000024e3: ADD
000024e4: PUSH2 0x2457
000024e7: JUMP
000024e8: JUMPDEST
000024e9: SWAP5
000024ea: SWAP8
000024eb: SWAP1
000024ec: SWAP7
000024ed: POP
000024ee: SWAP4
000024ef: SWAP5
000024f0: POP
000024f1: POP
000024f2: POP
000024f3: POP
000024f4: JUMP
000024f5: JUMPDEST
000024f6: PUSH1 0x00
000024f8: DUP1
000024f9: PUSH1 0x00
000024fb: PUSH1 0x40
000024fd: DUP5
000024fe: DUP7
000024ff: SUB
00002500: SLT
00002501: ISZERO
00002502: PUSH2 0x250a
00002505: JUMPI
00002506: PUSH1 0x00
00002508: DUP1
00002509: REVERT
0000250a: JUMPDEST
0000250b: DUP4
0000250c: CALLDATALOAD
0000250d: PUSH8 0xffffffffffffffff
00002516: DUP2
00002517: GT
00002518: ISZERO
00002519: PUSH2 0x2521
0000251c: JUMPI
0000251d: PUSH1 0x00
0000251f: DUP1
00002520: REVERT
00002521: JUMPDEST
00002522: PUSH2 0x252d
00002525: DUP7
00002526: DUP3
00002527: DUP8
00002528: ADD
00002529: PUSH2 0x2457
0000252c: JUMP
0000252d: JUMPDEST
0000252e: SWAP1
0000252f: SWAP5
00002530: POP
00002531: SWAP3
00002532: POP
00002533: POP
00002534: PUSH1 0x20
00002536: DUP5
00002537: ADD
00002538: CALLDATALOAD
00002539: PUSH2 0x2541
0000253c: DUP2
0000253d: PUSH2 0x240a
00002540: JUMP
00002541: JUMPDEST
00002542: DUP1
00002543: SWAP2
00002544: POP
00002545: POP
00002546: SWAP3
00002547: POP
00002548: SWAP3
00002549: POP
0000254a: SWAP3
0000254b: JUMP
0000254c: JUMPDEST
0000254d: PUSH1 0x00
0000254f: DUP1
00002550: PUSH1 0x40
00002552: DUP4
00002553: DUP6
00002554: SUB
00002555: SLT
00002556: ISZERO
00002557: PUSH2 0x255f
0000255a: JUMPI
0000255b: PUSH1 0x00
0000255d: DUP1
0000255e: REVERT
0000255f: JUMPDEST
00002560: DUP3
00002561: CALLDATALOAD
00002562: SWAP2
00002563: POP
00002564: PUSH1 0x20
00002566: DUP4
00002567: ADD
00002568: CALLDATALOAD
00002569: PUSH2 0x2571
0000256c: DUP2
0000256d: PUSH2 0x240a
00002570: JUMP
00002571: JUMPDEST
00002572: DUP1
00002573: SWAP2
00002574: POP
00002575: POP
00002576: SWAP3
00002577: POP
00002578: SWAP3
00002579: SWAP1
0000257a: POP
0000257b: JUMP
0000257c: JUMPDEST
0000257d: PUSH1 0x00
0000257f: PUSH1 0x20
00002581: DUP3
00002582: DUP5
00002583: SUB
00002584: SLT
00002585: ISZERO
00002586: PUSH2 0x258e
00002589: JUMPI
0000258a: PUSH1 0x00
0000258c: DUP1
0000258d: REVERT
0000258e: JUMPDEST
0000258f: POP
00002590: CALLDATALOAD
00002591: SWAP2
00002592: SWAP1
00002593: POP
00002594: JUMP
00002595: JUMPDEST
00002596: PUSH1 0x00
00002598: DUP1
00002599: PUSH1 0x40
0000259b: DUP4
0000259c: DUP6
0000259d: SUB
0000259e: SLT
0000259f: ISZERO
000025a0: PUSH2 0x25a8
000025a3: JUMPI
000025a4: PUSH1 0x00
000025a6: DUP1
000025a7: REVERT
000025a8: JUMPDEST
000025a9: POP
000025aa: POP
000025ab: DUP1
000025ac: CALLDATALOAD
000025ad: SWAP3
000025ae: PUSH1 0x20
000025b0: SWAP1
000025b1: SWAP2
000025b2: ADD
000025b3: CALLDATALOAD
000025b4: SWAP2
000025b5: POP
000025b6: JUMP
000025b7: JUMPDEST
000025b8: PUSH1 0x00
000025ba: DUP1
000025bb: PUSH1 0x40
000025bd: DUP4
000025be: DUP6
000025bf: SUB
000025c0: SLT
000025c1: ISZERO
000025c2: PUSH2 0x25ca
000025c5: JUMPI
000025c6: PUSH1 0x00
000025c8: DUP1
000025c9: REVERT
000025ca: JUMPDEST
000025cb: DUP3
000025cc: CALLDATALOAD
000025cd: PUSH2 0x25d5
000025d0: DUP2
000025d1: PUSH2 0x240a
000025d4: JUMP
000025d5: JUMPDEST
000025d6: SWAP5
000025d7: PUSH1 0x20
000025d9: SWAP4
000025da: SWAP1
000025db: SWAP4
000025dc: ADD
000025dd: CALLDATALOAD
000025de: SWAP4
000025df: POP
000025e0: POP
000025e1: POP
000025e2: JUMP
000025e3: JUMPDEST
000025e4: PUSH1 0x00
000025e6: DUP1
000025e7: PUSH1 0x40
000025e9: DUP4
000025ea: DUP6
000025eb: SUB
000025ec: SLT
000025ed: ISZERO
000025ee: PUSH2 0x25f6
000025f1: JUMPI
000025f2: PUSH1 0x00
000025f4: DUP1
000025f5: REVERT
000025f6: JUMPDEST
000025f7: DUP3
000025f8: CALLDATALOAD
000025f9: PUSH2 0x2601
000025fc: DUP2
000025fd: PUSH2 0x240a
00002600: JUMP
00002601: JUMPDEST
00002602: SWAP2
00002603: POP
00002604: PUSH1 0x20
00002606: DUP4
00002607: ADD
00002608: CALLDATALOAD
00002609: PUSH2 0x2571
0000260c: DUP2
0000260d: PUSH2 0x240a
00002610: JUMP
00002611: JUMPDEST
00002612: PUSH1 0x00
00002614: DUP1
00002615: PUSH1 0x00
00002617: DUP1
00002618: PUSH1 0x80
0000261a: DUP6
0000261b: DUP8
0000261c: SUB
0000261d: SLT
0000261e: ISZERO
0000261f: PUSH2 0x2627
00002622: JUMPI
00002623: PUSH1 0x00
00002625: DUP1
00002626: REVERT
00002627: JUMPDEST
00002628: DUP5
00002629: CALLDATALOAD
0000262a: SWAP4
0000262b: POP
0000262c: PUSH1 0x20
0000262e: DUP6
0000262f: ADD
00002630: CALLDATALOAD
00002631: PUSH2 0x2639
00002634: DUP2
00002635: PUSH2 0x240a
00002638: JUMP
00002639: JUMPDEST
0000263a: SWAP3
0000263b: POP
0000263c: PUSH1 0x40
0000263e: DUP6
0000263f: ADD
00002640: CALLDATALOAD
00002641: PUSH2 0x2649
00002644: DUP2
00002645: PUSH2 0x240a
00002648: JUMP
00002649: JUMPDEST
0000264a: SWAP4
0000264b: SWAP7
0000264c: SWAP3
0000264d: SWAP6
0000264e: POP
0000264f: SWAP3
00002650: SWAP4
00002651: PUSH1 0x60
00002653: ADD
00002654: CALLDATALOAD
00002655: SWAP3
00002656: POP
00002657: POP
00002658: JUMP
00002659: JUMPDEST
0000265a: PUSH1 0x00
0000265c: DUP1
0000265d: PUSH1 0x20
0000265f: DUP4
00002660: DUP6
00002661: SUB
00002662: SLT
00002663: ISZERO
00002664: PUSH2 0x266c
00002667: JUMPI
00002668: PUSH1 0x00
0000266a: DUP1
0000266b: REVERT
0000266c: JUMPDEST
0000266d: DUP3
0000266e: CALLDATALOAD
0000266f: PUSH8 0xffffffffffffffff
00002678: DUP2
00002679: GT
0000267a: ISZERO
0000267b: PUSH2 0x2683
0000267e: JUMPI
0000267f: PUSH1 0x00
00002681: DUP1
00002682: REVERT
00002683: JUMPDEST
00002684: PUSH2 0x268f
00002687: DUP6
00002688: DUP3
00002689: DUP7
0000268a: ADD
0000268b: PUSH2 0x2457
0000268e: JUMP
0000268f: JUMPDEST
00002690: SWAP1
00002691: SWAP7
00002692: SWAP1
00002693: SWAP6
00002694: POP
00002695: SWAP4
00002696: POP
00002697: POP
00002698: POP
00002699: POP
0000269a: JUMP
0000269b: JUMPDEST
0000269c: PUSH1 0x00
0000269e: DUP1
0000269f: PUSH1 0x00
000026a1: PUSH1 0x40
000026a3: DUP5
000026a4: DUP7
000026a5: SUB
000026a6: SLT
000026a7: ISZERO
000026a8: PUSH2 0x26b0
000026ab: JUMPI
000026ac: PUSH1 0x00
000026ae: DUP1
000026af: REVERT
000026b0: JUMPDEST
000026b1: DUP4
000026b2: CALLDATALOAD
000026b3: PUSH8 0xffffffffffffffff
000026bc: DUP2
000026bd: GT
000026be: ISZERO
000026bf: PUSH2 0x26c7
000026c2: JUMPI
000026c3: PUSH1 0x00
000026c5: DUP1
000026c6: REVERT
000026c7: JUMPDEST
000026c8: PUSH2 0x26d3
000026cb: DUP7
000026cc: DUP3
000026cd: DUP8
000026ce: ADD
000026cf: PUSH2 0x2457
000026d2: JUMP
000026d3: JUMPDEST
000026d4: SWAP1
000026d5: SWAP8
000026d6: SWAP1
000026d7: SWAP7
000026d8: POP
000026d9: PUSH1 0x20
000026db: SWAP6
000026dc: SWAP1
000026dd: SWAP6
000026de: ADD
000026df: CALLDATALOAD
000026e0: SWAP5
000026e1: SWAP4
000026e2: POP
000026e3: POP
000026e4: POP
000026e5: POP
000026e6: JUMP
000026e7: JUMPDEST
000026e8: PUSH1 0x00
000026ea: DUP1
000026eb: PUSH1 0x00
000026ed: PUSH1 0x60
000026ef: DUP5
000026f0: DUP7
000026f1: SUB
000026f2: SLT
000026f3: ISZERO
000026f4: PUSH2 0x26fc
000026f7: JUMPI
000026f8: PUSH1 0x00
000026fa: DUP1
000026fb: REVERT
000026fc: JUMPDEST
000026fd: DUP4
000026fe: CALLDATALOAD
000026ff: PUSH2 0x2707
00002702: DUP2
00002703: PUSH2 0x240a
00002706: JUMP
00002707: JUMPDEST
00002708: SWAP3
00002709: POP
0000270a: PUSH1 0x20
0000270c: DUP5
0000270d: ADD
0000270e: CALLDATALOAD
0000270f: PUSH2 0x2717
00002712: DUP2
00002713: PUSH2 0x240a
00002716: JUMP
00002717: JUMPDEST
00002718: SWAP2
00002719: POP
0000271a: PUSH1 0x40
0000271c: DUP5
0000271d: ADD
0000271e: CALLDATALOAD
0000271f: PUSH2 0x2541
00002722: DUP2
00002723: PUSH2 0x240a
00002726: JUMP
00002727: JUMPDEST
00002728: PUSH1 0x00
0000272a: PUSH1 0x20
0000272c: DUP3
0000272d: DUP5
0000272e: SUB
0000272f: SLT
00002730: ISZERO
00002731: PUSH2 0x2739
00002734: JUMPI
00002735: PUSH1 0x00
00002737: DUP1
00002738: REVERT
00002739: JUMPDEST
0000273a: DUP2
0000273b: CALLDATALOAD
0000273c: PUSH2 0x0ae2
0000273f: DUP2
00002740: PUSH2 0x240a
00002743: JUMP
00002744: JUMPDEST
00002745: PUSH1 0x00
00002747: PUSH1 0x20
00002749: DUP3
0000274a: DUP5
0000274b: SUB
0000274c: SLT
0000274d: ISZERO
0000274e: PUSH2 0x2756
00002751: JUMPI
00002752: PUSH1 0x00
00002754: DUP1
00002755: REVERT
00002756: JUMPDEST
00002757: DUP2
00002758: MLOAD
00002759: PUSH2 0x0ae2
0000275c: DUP2
0000275d: PUSH2 0x240a
00002760: JUMP
00002761: JUMPDEST
00002762: PUSH1 0x00
00002764: PUSH1 0x20
00002766: DUP3
00002767: DUP5
00002768: SUB
00002769: SLT
0000276a: ISZERO
0000276b: PUSH2 0x2773
0000276e: JUMPI
0000276f: PUSH1 0x00
00002771: DUP1
00002772: REVERT
00002773: JUMPDEST
00002774: DUP2
00002775: MLOAD
00002776: DUP1
00002777: ISZERO
00002778: ISZERO
00002779: DUP2
0000277a: EQ
0000277b: PUSH2 0x0ae2
0000277e: JUMPI
0000277f: PUSH1 0x00
00002781: DUP1
00002782: REVERT
00002783: JUMPDEST
00002784: PUSH1 0x20
00002786: DUP1
00002787: DUP3
00002788: MSTORE
00002789: PUSH1 0x2e
0000278b: SWAP1
0000278c: DUP3
0000278d: ADD
0000278e: MSTORE
0000278f: PUSH32 0x496e697469616c697a61626c653a20636f6e747261637420697320616c726561
000027b0: PUSH1 0x40
000027b2: DUP3
000027b3: ADD
000027b4: MSTORE
000027b5: PUSH14 0x191e481a5b9a5d1a585b1a5e9959
000027c4: PUSH1 0x92
000027c6: SHL
000027c7: PUSH1 0x60
000027c9: DUP3
000027ca: ADD
000027cb: MSTORE
000027cc: PUSH1 0x80
000027ce: ADD
000027cf: SWAP1
000027d0: JUMP
000027d1: JUMPDEST
000027d2: PUSH4 0x4e487b71
000027d7: PUSH1 0xe0
000027d9: SHL
000027da: PUSH1 0x00
000027dc: MSTORE
000027dd: PUSH1 0x11
000027df: PUSH1 0x04
000027e1: MSTORE
000027e2: PUSH1 0x24
000027e4: PUSH1 0x00
000027e6: REVERT
000027e7: JUMPDEST
000027e8: DUP1
000027e9: DUP3
000027ea: MUL
000027eb: DUP2
000027ec: ISZERO
000027ed: DUP3
000027ee: DUP3
000027ef: DIV
000027f0: DUP5
000027f1: EQ
000027f2: OR
000027f3: PUSH2 0x0717
000027f6: JUMPI
000027f7: PUSH2 0x0717
000027fa: PUSH2 0x27d1
000027fd: JUMP
000027fe: JUMPDEST
000027ff: DUP2
00002800: DUP2
00002801: SUB
00002802: DUP2
00002803: DUP2
00002804: GT
00002805: ISZERO
00002806: PUSH2 0x0717
00002809: JUMPI
0000280a: PUSH2 0x0717
0000280d: PUSH2 0x27d1
00002810: JUMP
00002811: JUMPDEST
00002812: PUSH1 0x00
00002814: JUMPDEST
00002815: DUP4
00002816: DUP2
00002817: LT
00002818: ISZERO
00002819: PUSH2 0x282c
0000281c: JUMPI
0000281d: DUP2
0000281e: DUP2
0000281f: ADD
00002820: MLOAD
00002821: DUP4
00002822: DUP3
00002823: ADD
00002824: MSTORE
00002825: PUSH1 0x20
00002827: ADD
00002828: PUSH2 0x2814
0000282b: JUMP
0000282c: JUMPDEST
0000282d: POP
0000282e: POP
0000282f: PUSH1 0x00
00002831: SWAP2
00002832: ADD
00002833: MSTORE
00002834: JUMP
00002835: JUMPDEST
00002836: PUSH1 0x00
00002838: DUP2
00002839: MLOAD
0000283a: DUP1
0000283b: DUP5
0000283c: MSTORE
0000283d: PUSH2 0x284d
00002840: DUP2
00002841: PUSH1 0x20
00002843: DUP7
00002844: ADD
00002845: PUSH1 0x20
00002847: DUP7
00002848: ADD
00002849: PUSH2 0x2811
0000284c: JUMP
0000284d: JUMPDEST
0000284e: PUSH1 0x1f
00002850: ADD
00002851: PUSH1 0x1f
00002853: NOT
00002854: AND
00002855: SWAP3
00002856: SWAP1
00002857: SWAP3
00002858: ADD
00002859: PUSH1 0x20
0000285b: ADD
0000285c: SWAP3
0000285d: SWAP2
0000285e: POP
0000285f: POP
00002860: JUMP
00002861: JUMPDEST
00002862: DUP4
00002863: DUP2
00002864: MSTORE
00002865: PUSH1 0x01
00002867: PUSH1 0x01
00002869: PUSH1 0xa0
0000286b: SHL
0000286c: SUB
0000286d: DUP4
0000286e: AND
0000286f: PUSH1 0x20
00002871: DUP3
00002872: ADD
00002873: MSTORE
00002874: PUSH1 0x60
00002876: PUSH1 0x40
00002878: DUP3
00002879: ADD
0000287a: DUP2
0000287b: SWAP1
0000287c: MSTORE
0000287d: PUSH1 0x00
0000287f: SWAP1
00002880: PUSH2 0x288b
00002883: SWAP1
00002884: DUP4
00002885: ADD
00002886: DUP5
00002887: PUSH2 0x2835
0000288a: JUMP
0000288b: JUMPDEST
0000288c: SWAP6
0000288d: SWAP5
0000288e: POP
0000288f: POP
00002890: POP
00002891: POP
00002892: POP
00002893: JUMP
00002894: JUMPDEST
00002895: PUSH1 0x00
00002897: DUP3
00002898: PUSH2 0x28b1
0000289b: JUMPI
0000289c: PUSH4 0x4e487b71
000028a1: PUSH1 0xe0
000028a3: SHL
000028a4: PUSH1 0x00
000028a6: MSTORE
000028a7: PUSH1 0x12
000028a9: PUSH1 0x04
000028ab: MSTORE
000028ac: PUSH1 0x24
000028ae: PUSH1 0x00
000028b0: REVERT
000028b1: JUMPDEST
000028b2: POP
000028b3: DIV
000028b4: SWAP1
000028b5: JUMP
000028b6: JUMPDEST
000028b7: DUP1
000028b8: DUP3
000028b9: ADD
000028ba: DUP1
000028bb: DUP3
000028bc: GT
000028bd: ISZERO
000028be: PUSH2 0x0717
000028c1: JUMPI
000028c2: PUSH2 0x0717
000028c5: PUSH2 0x27d1
000028c8: JUMP
000028c9: JUMPDEST
000028ca: PUSH1 0x00
000028cc: DUP3
000028cd: MLOAD
000028ce: PUSH2 0x28db
000028d1: DUP2
000028d2: DUP5
000028d3: PUSH1 0x20
000028d5: DUP8
000028d6: ADD
000028d7: PUSH2 0x2811
000028da: JUMP
000028db: JUMPDEST
000028dc: SWAP2
000028dd: SWAP1
000028de: SWAP2
000028df: ADD
000028e0: SWAP3
000028e1: SWAP2
000028e2: POP
000028e3: POP
000028e4: JUMP
000028e5: JUMPDEST
000028e6: PUSH32 0x416363657373436f6e74726f6c3a206163636f756e7420000000000000000000
00002907: DUP2
00002908: MSTORE
00002909: PUSH1 0x00
0000290b: DUP4
0000290c: MLOAD
0000290d: PUSH2 0x291d
00002910: DUP2
00002911: PUSH1 0x17
00002913: DUP6
00002914: ADD
00002915: PUSH1 0x20
00002917: DUP9
00002918: ADD
00002919: PUSH2 0x2811
0000291c: JUMP
0000291d: JUMPDEST
0000291e: PUSH17 0x01034b99036b4b9b9b4b733903937b6329
00002930: PUSH1 0x7d
00002932: SHL
00002933: PUSH1 0x17
00002935: SWAP2
00002936: DUP5
00002937: ADD
00002938: SWAP2
00002939: DUP3
0000293a: ADD
0000293b: MSTORE
0000293c: DUP4
0000293d: MLOAD
0000293e: PUSH2 0x294e
00002941: DUP2
00002942: PUSH1 0x28
00002944: DUP5
00002945: ADD
00002946: PUSH1 0x20
00002948: DUP9
00002949: ADD
0000294a: PUSH2 0x2811
0000294d: JUMP
0000294e: JUMPDEST
0000294f: ADD
00002950: PUSH1 0x28
00002952: ADD
00002953: SWAP5
00002954: SWAP4
00002955: POP
00002956: POP
00002957: POP
00002958: POP
00002959: JUMP
0000295a: JUMPDEST
0000295b: PUSH1 0x20
0000295d: DUP2
0000295e: MSTORE
0000295f: PUSH1 0x00
00002961: PUSH2 0x0ae2
00002964: PUSH1 0x20
00002966: DUP4
00002967: ADD
00002968: DUP5
00002969: PUSH2 0x2835
0000296c: JUMP
0000296d: JUMPDEST
0000296e: DUP2
0000296f: MLOAD
00002970: MLOAD
00002971: PUSH1 0x60
00002973: DUP3
00002974: ADD
00002975: SWAP1
00002976: PUSH1 0x0f
00002978: DUP2
00002979: LT
0000297a: PUSH2 0x2993
0000297d: JUMPI
0000297e: PUSH4 0x4e487b71
00002983: PUSH1 0xe0
00002985: SHL
00002986: PUSH1 0x00
00002988: MSTORE
00002989: PUSH1 0x21
0000298b: PUSH1 0x04
0000298d: MSTORE
0000298e: PUSH1 0x24
00002990: PUSH1 0x00
00002992: REVERT
00002993: JUMPDEST
00002994: DUP3
00002995: MSTORE
00002996: PUSH1 0x20
00002998: DUP4
00002999: DUP2
0000299a: ADD
0000299b: MLOAD
0000299c: PUSH1 0x01
0000299e: PUSH1 0x01
000029a0: PUSH1 0xa0
000029a2: SHL
000029a3: SUB
000029a4: AND
000029a5: SWAP1
000029a6: DUP4
000029a7: ADD
000029a8: MSTORE
000029a9: PUSH1 0x40
000029ab: SWAP3
000029ac: DUP4
000029ad: ADD
000029ae: MLOAD
000029af: ISZERO
000029b0: ISZERO
000029b1: SWAP3
000029b2: SWAP1
000029b3: SWAP2
000029b4: ADD
000029b5: SWAP2
000029b6: SWAP1
000029b7: SWAP2
000029b8: MSTORE
000029b9: SWAP1
000029ba: JUMP
000029bb: JUMPDEST
000029bc: PUSH4 0x4e487b71
000029c1: PUSH1 0xe0
000029c3: SHL
000029c4: PUSH1 0x00
000029c6: MSTORE
000029c7: PUSH1 0x32
000029c9: PUSH1 0x04
000029cb: MSTORE
000029cc: PUSH1 0x24
000029ce: PUSH1 0x00
000029d0: REVERT
000029d1: JUMPDEST
000029d2: PUSH4 0x4e487b71
000029d7: PUSH1 0xe0
000029d9: SHL
000029da: PUSH1 0x00
000029dc: MSTORE
000029dd: PUSH1 0x41
000029df: PUSH1 0x04
000029e1: MSTORE
000029e2: PUSH1 0x24
000029e4: PUSH1 0x00
000029e6: REVERT
000029e7: JUMPDEST
000029e8: PUSH1 0x00
000029ea: DUP2
000029eb: PUSH2 0x29f6
000029ee: JUMPI
000029ef: PUSH2 0x29f6
000029f2: PUSH2 0x27d1
000029f5: JUMP
000029f6: JUMPDEST
000029f7: POP
000029f8: PUSH1 0x00
000029fa: NOT
000029fb: ADD
000029fc: SWAP1
000029fd: JUMP
000029fe: JUMPDEST
000029ff: PUSH4 0x4e487b71
00002a04: PUSH1 0xe0
00002a06: SHL
00002a07: PUSH1 0x00
00002a09: MSTORE
00002a0a: PUSH1 0x31
00002a0c: PUSH1 0x04
00002a0e: MSTORE
00002a0f: PUSH1 0x24
00002a11: PUSH1 0x00
00002a13: REVERT
00002a14: INVALID
00002a15: PUSH20 0x3bac3dca102687aa08c854c5f9067fc424f98fd8
00002a2a: UNKNOWN(0xE9)
00002a2b: UNKNOWN(0x0E)
00002a2c: COINBASE
00002a2d: UNKNOWN(0xAD)
00002a2e: PUSH12 0x73aecc59a4fda26469706673
00002a3b: PC
00002a3c: UNKNOWN(0x22)
00002a3d: SLT
00002a3e: KECCAK256
00002a3f: UNKNOWN(0xE7)
00002a40: UNKNOWN(0x2E)
00002a41: EXTCODEHASH
00002a42: SGT
00002a43: DUP6
00002a44: UNKNOWN(0xB9)
00002a45: UNKNOWN(0xB1)
00002a46: UNKNOWN(0x21)
00002a47: UNKNOWN(0xAB)
00002a48: UNKNOWN(0x25)
00002a49: DUP9
00002a4a: JUMPDEST
00002a4b: JUMP
00002a4c: PUSH21 0xc62d66b957590dc193eeba8176ac32bf4d1764736f
00002a62: PUSH13

Findings

validated = confirmed for call sinks; sink observed for others
Severity Category Tool Title Confidence Validated Confirmed Details
high other detector Untrusted CALL target/value reachable 60 no no
view
trace_id: 0x9fa23b641eaae52469043bdc22e14c357eaa8b274c925bc7fa2e9e1b12301ab6
call_targets: 0x29353f77c6b0d3772d73e708cc8e1fca08c80c11
target_varies: no
classification: constant_target
validation_json
{
    "sink": "CALL",
    "errors": 0,
    "status": "sink_reached",
    "attempts": 1,
    "trace_id": "0x9fa23b641eaae52469043bdc22e14c357eaa8b274c925bc7fa2e9e1b12301ab6",
    "confirmed": false,
    "trace_mode": "callTracer",
    "call_targets": [
        "0x29353f77c6b0d3772d73e708cc8e1fca08c80c11"
    ],
    "matched_probe": null,
    "target_varies": false,
    "classification": "constant_target"
}
witness_json
{
    "notes": "heuristic witness; entrypoints are best-effort selectors with zeroed calldata",
    "constraints": [],
    "entrypoints": [
        {
            "calldata": "0xc80493cf",
            "selector": "0xc80493cf",
            "calldata_variants": [
                "0xc80493cf",
                "0xc80493cf0000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0xca15c873",
            "selector": "0xca15c873",
            "calldata_variants": [
                "0xca15c873",
                "0xca15c8730000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0xd547741f",
            "selector": "0xd547741f",
            "calldata_variants": [
                "0xd547741f",
                "0xd547741f0000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0xe91d6390",
            "selector": "0xe91d6390",
            "calldata_variants": [
                "0xe91d6390",
                "0xe91d63900000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0xff55cd40",
            "selector": "0xff55cd40",
            "calldata_variants": [
                "0xff55cd40",
                "0xff55cd400000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0xb0cba84e",
            "selector": "0xb0cba84e",
            "calldata_variants": [
                "0xb0cba84e",
                "0xb0cba84e0000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0xbbc4e8c2",
            "selector": "0xbbc4e8c2",
            "calldata_variants": [
                "0xbbc4e8c2",
                "0xbbc4e8c20000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0xc0c53b8b",
            "selector": "0xc0c53b8b",
            "calldata_variants": [
                "0xc0c53b8b",
                "0xc0c53b8b0000000000000000000000000000000000000000000000000000000000000000"
            ]
        }
    ]
}
evidence_json
{
    "examples": [
        {
            "pc": 2150,
            "opcode": "CALL",
            "returndata_checked": null,
            "value_expression_category": "computed",
            "target_expression_category": "computed"
        },
        {
            "pc": 4295,
            "opcode": "CALL",
            "returndata_checked": null,
            "value_expression_category": "computed",
            "target_expression_category": "computed"
        },
        {
            "pc": 5857,
            "opcode": "CALL",
            "returndata_checked": null,
            "value_expression_category": "computed",
            "target_expression_category": "computed"
        }
    ],
    "call_count": 5,
    "guards_detected": [],
    "untrusted_call_count": 5
}
high other slither Wallets.refundGasBySchain(bytes32,address,uint256,bool) (contracts/test/TestWallets.sol#53-68) sends eth to arbitrary user 85 no
view
evidence_json
{
    "impact": "High",
    "detector": "arbitrary-send-eth",
    "elements": [
        {
            "name": "refundGasBySchain",
            "type": "function",
            "source_mapping": {
                "lines": [
                    53,
                    54,
                    55,
                    56,
                    57,
                    58,
                    59,
                    60,
                    61,
                    62,
                    63,
                    64,
                    65,
                    66,
                    67,
                    68
                ],
                "start": 1776,
                "length": 531,
                "ending_column": 6,
                "is_dependency": false,
                "filename_short": "contracts/test/TestWallets.sol",
                "starting_column": 5,
                "filename_absolute": "/tmp/slither-3rzqsamt/contracts/test/TestWallets.sol",
                "filename_relative": "contracts/test/TestWallets.sol"
            },
            "type_specific_fields": {
                "parent": {
                    "name": "Wallets",
                    "type": "contract",
                    "source_mapping": {
                        "lines": [
                            39,
                            40,
                            41,
                            42,
                            43,
                            44,
                            45,
                            46,
                            47,
                            48,
                            49,
                            50,
                            51,
                            52,
                            53,
                            54,
                            55,
                            56,
                            57,
                            58,
                            59,
                            60,
                            61,
                            62,
                            63,
                            64,
                            65,
                            66,
                            67,
                            68,
                            69,
                            70,
                            71,
                            72,
                            73,
                            74,
                            75,
                            76,
                            77,
                            78,
                            79,
                            80
                        ],
                        "start": 1320,
                        "length": 1548,
                        "ending_column": 2,
                        "is_dependency": false,
                        "filename_short": "contracts/test/TestWallets.sol",
                        "starting_column": 1,
                        "filename_absolute": "/tmp/slither-3rzqsamt/contracts/test/TestWallets.sol",
                        "filename_relative": "contracts/test/TestWallets.sol"
                    }
                },
                "signature": "refundGasBySchain(bytes32,address,uint256,bool)"
            }
        },
        {
            "name": "spender.transfer(amount)",
            "type": "node",
            "source_mapping": {
                "lines": [
                    67
                ],
                "start": 2276,
                "length": 24,
                "ending_column": 33,
                "is_dependency": false,
                "filename_short": "contracts/test/TestWallets.sol",
                "starting_column": 9,
                "filename_absolute": "/tmp/slither-3rzqsamt/contracts/test/TestWallets.sol",
                "filename_relative": "contracts/test/TestWallets.sol"
            },
            "type_specific_fields": {
                "parent": {
                    "name": "refundGasBySchain",
                    "type": "function",
                    "source_mapping": {
                        "lines": [
                            53,
                            54,
                            55,
                            56,
                            57,
                            58,
                            59,
                            60,
                            61,
                            62,
                            63,
                            64,
                            65,
                            66,
                            67,
                            68
                        ],
                        "start": 1776,
                        "length": 531,
                        "ending_column": 6,
                        "is_dependency": false,
                        "filename_short": "contracts/test/TestWallets.sol",
                        "starting_column": 5,
                        "filename_absolute": "/tmp/slither-3rzqsamt/contracts/test/TestWallets.sol",
                        "filename_relative": "contracts/test/TestWallets.sol"
                    },
                    "type_specific_fields": {
                        "parent": {
                            "name": "Wallets",
                            "type": "contract",
                            "source_mapping": {
                                "lines": [
                                    39,
                                    40,
                                    41,
                                    42,
                                    43,
                                    44,
                                    45,
                                    46,
                                    47,
                                    48,
                                    49,
                                    50,
                                    51,
                                    52,
                                    53,
                                    54,
                                    55,
                                    56,
                                    57,
                                    58,
                                    59,
                                    60,
                                    61,
                                    62,
                                    63,
                                    64,
                                    65,
                                    66,
                                    67,
                                    68,
                                    69,
                                    70,
                                    71,
                                    72,
                                    73,
                                    74,
                                    75,
                                    76,
                                    77,
                                    78,
                                    79,
                                    80
                                ],
                                "start": 1320,
                                "length": 1548,
                                "ending_column": 2,
                                "is_dependency": false,
                                "filename_short": "contracts/test/TestWallets.sol",
                                "starting_column": 1,
                                "filename_absolute": "/tmp/slither-3rzqsamt/contracts/test/TestWallets.sol",
                                "filename_relative": "contracts/test/TestWallets.sol"
                            }
                        },
                        "signature": "refundGasBySchain(bytes32,address,uint256,bool)"
                    }
                }
            }
        }
    ],
    "locations": [
        {
            "file": "contracts/test/TestWallets.sol",
            "name": "refundGasBySchain",
            "type": "function",
            "lines": [
                53,
                54,
                55,
                56,
                57,
                58,
                59,
                60,
                61,
                62,
                63,
                64,
                65,
                66,
                67,
                68
            ]
        },
        {
            "file": "contracts/test/TestWallets.sol",
            "name": "spender.transfer(amount)",
            "type": "node",
            "lines": [
                67
            ]
        }
    ],
    "description": "Wallets.refundGasBySchain(bytes32,address,uint256,bool) (contracts/test/TestWallets.sol#53-68) sends eth to arbitrary user\n\tDangerous calls:\n\t- spender.transfer(amount) (contracts/test/TestWallets.sol#67)"
}
high other detector ETH value transfer possible 55 no no
view
trace_id: 0x9fa23b641eaae52469043bdc22e14c357eaa8b274c925bc7fa2e9e1b12301ab6
call_targets: 0x29353f77c6b0d3772d73e708cc8e1fca08c80c11
target_varies: no
classification: constant_target
validation_json
{
    "sink": "CALL",
    "errors": 0,
    "status": "sink_reached",
    "attempts": 1,
    "trace_id": "0x9fa23b641eaae52469043bdc22e14c357eaa8b274c925bc7fa2e9e1b12301ab6",
    "confirmed": false,
    "trace_mode": "callTracer",
    "call_targets": [
        "0x29353f77c6b0d3772d73e708cc8e1fca08c80c11"
    ],
    "matched_probe": null,
    "target_varies": false,
    "classification": "constant_target"
}
witness_json
{
    "notes": "heuristic witness; entrypoints are best-effort selectors with zeroed calldata",
    "constraints": [],
    "entrypoints": [
        {
            "calldata": "0xc80493cf",
            "selector": "0xc80493cf",
            "calldata_variants": [
                "0xc80493cf",
                "0xc80493cf0000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0xca15c873",
            "selector": "0xca15c873",
            "calldata_variants": [
                "0xca15c873",
                "0xca15c8730000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0xd547741f",
            "selector": "0xd547741f",
            "calldata_variants": [
                "0xd547741f",
                "0xd547741f0000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0xe91d6390",
            "selector": "0xe91d6390",
            "calldata_variants": [
                "0xe91d6390",
                "0xe91d63900000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0xff55cd40",
            "selector": "0xff55cd40",
            "calldata_variants": [
                "0xff55cd40",
                "0xff55cd400000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0xb0cba84e",
            "selector": "0xb0cba84e",
            "calldata_variants": [
                "0xb0cba84e",
                "0xb0cba84e0000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0xbbc4e8c2",
            "selector": "0xbbc4e8c2",
            "calldata_variants": [
                "0xbbc4e8c2",
                "0xbbc4e8c20000000000000000000000000000000000000000000000000000000000000000"
            ]
        },
        {
            "calldata": "0xc0c53b8b",
            "selector": "0xc0c53b8b",
            "calldata_variants": [
                "0xc0c53b8b",
                "0xc0c53b8b0000000000000000000000000000000000000000000000000000000000000000"
            ]
        }
    ]
}
evidence_json
{
    "examples": [
        {
            "pc": 2150,
            "opcode": "CALL",
            "returndata_checked": null,
            "value_expression_category": "computed",
            "target_expression_category": "computed"
        },
        {
            "pc": 4295,
            "opcode": "CALL",
            "returndata_checked": null,
            "value_expression_category": "computed",
            "target_expression_category": "computed"
        },
        {
            "pc": 5857,
            "opcode": "CALL",
            "returndata_checked": null,
            "value_expression_category": "computed",
            "target_expression_category": "computed"
        }
    ],
    "eth_value_calls": 5,
    "guards_detected": []
}
high other codex ERC20 bridge accounting trusts the requested amount instead of the amount actually received 85 no
view
evidence_json
{
    "evidence": "On mainnet, the code builds the outbound message and increments `transferredAmount` using the caller-supplied `amount`, then performs `safeTransferFrom` with no balance-delta check. On schain-native ERC20 transfers, `_saveTransferredAmount(..., amount)` is also done before `transferFrom`, again assuming the nominal amount was received.",
    "locations": [
        "contracts/mainnet/DepositBoxes/DepositBoxERC20.sol:698",
        "contracts/mainnet/DepositBoxes/DepositBoxERC20.sol:704",
        "contracts/mainnet/DepositBoxes/DepositBoxERC20.sol:705",
        "contracts/schain/TokenManagers/TokenManagerERC20.sol:339",
        "contracts/schain/TokenManagers/TokenManagerERC20.sol:348",
        "contracts/schain/TokenManagers/TokenManagerERC20.sol:350"
    ],
    "recommendation": "Measure `balanceBefore`/`balanceAfter` around every ERC20 pull and bridge only the actual received amount. Revert if the received amount is smaller than requested unless the token type is explicitly unsupported. Apply the same balance-delta accounting anywhere ERC20s are locked rather than burned.",
    "exploit_scenario": "A user bridges a fee-on-transfer or deflationary ERC20. `DepositBoxERC20` records and messages the full `amount` before/without checking how many tokens the bridge actually received. The destination chain credits the full amount, but the source bridge locked less. The attacker can later exit the full credited balance and drain other users' liquidity or leave the bridge permanently undercollateralized. The same nominal-amount assumption exists in the schain-native ERC20 path when a token is locked for schain-to-schain transfer."
}
medium reentrancy slither Reentrancy in FallbackEthTester.receive() (contracts/test/FallbackEthTester.sol#55-62): 75 no
view
evidence_json
{
    "impact": "Medium",
    "detector": "reentrancy-no-eth",
    "elements": [
        {
            "name": "receive",
            "type": "function",
            "source_mapping": {
                "lines": [
                    55,
                    56,
                    57,
                    58,
                    59,
                    60,
                    61,
                    62
                ],
                "start": 1746,
                "length": 336,
                "ending_column": 6,
                "is_dependency": false,
                "filename_short": "contracts/test/FallbackEthTester.sol",
                "starting_column": 5,
                "filename_absolute": "/tmp/slither-3rzqsamt/contracts/test/FallbackEthTester.sol",
                "filename_relative": "contracts/test/FallbackEthTester.sol"
            },
            "type_specific_fields": {
                "parent": {
                    "name": "FallbackEthTester",
                    "type": "contract",
                    "source_mapping": {
                        "lines": [
                            36,
                            37,
                            38,
                            39,
                            40,
                            41,
                            42,
                            43,
                            44,
                            45,
                            46,
                            47,
                            48,
                            49,
                            50,
                            51,
                            52,
                            53,
                            54,
                            55,
                            56,
                            57,
                            58,
                            59,
                            60,
                            61,
                            62,
                            63,
                            64,
                            65,
                            66,
                            67,
                            68,
                            69,
                            70,
                            71,
                            72,
                            73,
                            74,
                            75,
                            76,
                            77
                        ],
                        "start": 1231,
                        "length": 1286,
                        "ending_column": 2,
                        "is_dependency": false,
                        "filename_short": "contracts/test/FallbackEthTester.sol",
                        "starting_column": 1,
                        "filename_absolute": "/tmp/slither-3rzqsamt/contracts/test/FallbackEthTester.sol",
                        "filename_relative": "contracts/test/FallbackEthTester.sol"
                    }
                },
                "signature": "receive()"
            }
        },
        {
            "name": "communityPool.withdrawFunds(schainName,balance)",
            "type": "node",
            "source_mapping": {
                "lines": [
                    59
                ],
                "start": 1977,
                "length": 48,
                "ending_column": 61,
                "is_dependency": false,
                "filename_short": "contracts/test/FallbackEthTester.sol",
                "starting_column": 13,
                "filename_absolute": "/tmp/slither-3rzqsamt/contracts/test/FallbackEthTester.sol",
                "filename_relative": "contracts/test/FallbackEthTester.sol"
            },
            "additional_fields": {
                "underlying_type": "external_calls"
            },
            "type_specific_fields": {
                "parent": {
                    "name": "receive",
                    "type": "function",
                    "source_mapping": {
                        "lines": [
                            55,
                            56,
                            57,
                            58,
                            59,
                            60,
                            61,
                            62
                        ],
                        "start": 1746,
                        "length": 336,
                        "ending_column": 6,
                        "is_dependency": false,
                        "filename_short": "contracts/test/FallbackEthTester.sol",
                        "starting_column": 5,
                        "filename_absolute": "/tmp/slither-3rzqsamt/contracts/test/FallbackEthTester.sol",
                        "filename_relative": "contracts/test/FallbackEthTester.sol"
                    },
                    "type_specific_fields": {
                        "parent": {
                            "name": "FallbackEthTester",
                            "type": "contract",
                            "source_mapping": {
                                "lines": [
                                    36,
                                    37,
                                    38,
                                    39,
                                    40,
                                    41,
                                    42,
                                    43,
                                    44,
                                    45,
                                    46,
                                    47,
                                    48,
                                    49,
                                    50,
                                    51,
                                    52,
                                    53,
                                    54,
                                    55,
                                    56,
                                    57,
                                    58,
                                    59,
                                    60,
                                    61,
                                    62,
                                    63,
                                    64,
                                    65,
                                    66,
                                    67,
                                    68,
                                    69,
                                    70,
                                    71,
                                    72,
                                    73,
                                    74,
                                    75,
                                    76,
                                    77
                                ],
                                "start": 1231,
                                "length": 1286,
                                "ending_column": 2,
                                "is_dependency": false,
                                "filename_short": "contracts/test/FallbackEthTester.sol",
                                "starting_column": 1,
                                "filename_absolute": "/tmp/slither-3rzqsamt/contracts/test/FallbackEthTester.sol",
                                "filename_relative": "contracts/test/FallbackEthTester.sol"
                            }
                        },
                        "signature": "receive()"
                    }
                }
            }
        },
        {
            "name": "_receiveInProgress = false",
            "type": "node",
            "source_mapping": {
                "lines": [
                    60
                ],
                "start": 2039,
                "length": 26,
                "ending_column": 39,
                "is_dependency": false,
                "filename_short": "contracts/test/FallbackEthTester.sol",
                "starting_column": 13,
                "filename_absolute": "/tmp/slither-3rzqsamt/contracts/test/FallbackEthTester.sol",
                "filename_relative": "contracts/test/FallbackEthTester.sol"
            },
            "additional_fields": {
                "variable_name": "_receiveInProgress",
                "underlying_type": "variables_written"
            },
            "type_specific_fields": {
                "parent": {
                    "name": "receive",
                    "type": "function",
                    "source_mapping": {
                        "lines": [
                            55,
                            56,
                            57,
                            58,
                            59,
                            60,
                            61,
                            62
                        ],
                        "start": 1746,
                        "length": 336,
                        "ending_column": 6,
                        "is_dependency": false,
                        "filename_short": "contracts/test/FallbackEthTester.sol",
                        "starting_column": 5,
                        "filename_absolute": "/tmp/slither-3rzqsamt/contracts/test/FallbackEthTester.sol",
                        "filename_relative": "contracts/test/FallbackEthTester.sol"
                    },
                    "type_specific_fields": {
                        "parent": {
                            "name": "FallbackEthTester",
                            "type": "contract",
                            "source_mapping": {
                                "lines": [
                                    36,
                                    37,
                                    38,
                                    39,
                                    40,
                                    41,
                                    42,
                                    43,
                                    44,
                                    45,
                                    46,
                                    47,
                                    48,
                                    49,
                                    50,
                                    51,
                                    52,
                                    53,
                                    54,
                                    55,
                                    56,
                                    57,
                                    58,
                                    59,
                                    60,
                                    61,
                                    62,
                                    63,
                                    64,
                                    65,
                                    66,
                                    67,
                                    68,
                                    69,
                                    70,
                                    71,
                                    72,
                                    73,
                                    74,
                                    75,
                                    76,
                                    77
                                ],
                                "start": 1231,
                                "length": 1286,
                                "ending_column": 2,
                                "is_dependency": false,
                                "filename_short": "contracts/test/FallbackEthTester.sol",
                                "starting_column": 1,
                                "filename_absolute": "/tmp/slither-3rzqsamt/contracts/test/FallbackEthTester.sol",
                                "filename_relative": "contracts/test/FallbackEthTester.sol"
                            }
                        },
                        "signature": "receive()"
                    }
                }
            }
        }
    ],
    "locations": [
        {
            "file": "contracts/test/FallbackEthTester.sol",
            "name": "receive",
            "type": "function",
            "lines": [
                55,
                56,
                57,
                58,
                59,
                60,
                61,
                62
            ]
        },
        {
            "file": "contracts/test/FallbackEthTester.sol",
            "name": "communityPool.withdrawFunds(schainName,balance)",
            "type": "node",
            "lines": [
                59
            ]
        },
        {
            "file": "contracts/test/FallbackEthTester.sol",
            "name": "_receiveInProgress = false",
            "type": "node",
            "lines": [
                60
            ]
        }
    ],
    "description": "Reentrancy in FallbackEthTester.receive() (contracts/test/FallbackEthTester.sol#55-62):\n\tExternal calls:\n\t- communityPool.withdrawFunds(schainName,balance) (contracts/test/FallbackEthTester.sol#59)\n\tState variables written after the call(s):\n\t- _receiveInProgress = false (contracts/test/FallbackEthTester.sol#60)\n\tFallbackEthTester._receiveInProgress (contracts/test/FallbackEthTester.sol#42) can be used in cross function reentrancies:\n\t- FallbackEthTester.receive() (contracts/test/FallbackEthTester.sol#55-62)"
}
medium other codex Delayed ERC20 withdrawals clear user claims before confirming token delivery 75 no
view
evidence_json
{
    "evidence": "`retrieveFor` removes or marks transfers as `COMPLETED` before calling `_doNTransfers`. `_doNTransfers` catches transfer failures and only emits `TransferSkipped`, without restoring the queue entry or status.",
    "locations": [
        "contracts/mainnet/DepositBoxes/DepositBoxERC20.sol:631",
        "contracts/mainnet/DepositBoxes/DepositBoxERC20.sol:635",
        "contracts/mainnet/DepositBoxes/DepositBoxERC20.sol:651",
        "contracts/mainnet/DepositBoxes/DepositBoxERC20.sol:734",
        "contracts/mainnet/DepositBoxes/DepositBoxERC20.sol:737"
    ],
    "recommendation": "Do not mutate delayed-transfer state until the token transfer succeeds. Revert failed payouts, or leave the transfer pending so the user can retry later. If partial progress is needed, persist an explicit failed state with an admin/user recovery path instead of deleting the claim.",
    "exploit_scenario": "When a delayed transfer becomes withdrawable, `retrieveFor` marks it completed or deletes it from the queue before attempting the ERC20 transfer. If the token transfer then fails, the call is swallowed and only `TransferSkipped` is emitted. A token admin can pause or blacklist transfers right before unlock, or a nonstandard token can fail transfer, causing the receiver's claim to be irreversibly erased while the tokens remain stuck in the bridge contract."
}
low oracle codex `CommunityLocker.setGasPrice` accepts arbitrary caller-supplied oracle values 65 no
view
evidence_json
{
    "evidence": "The function has no access-control modifier, the signature argument is unnamed/unused, and the intended `messageProxy.verifySignature(...)` check is commented out.",
    "locations": [
        "contracts/schain/CommunityLocker.sol:252",
        "contracts/schain/CommunityLocker.sol:257",
        "contracts/schain/CommunityLocker.sol:262",
        "contracts/schain/CommunityLocker.sol:272"
    ],
    "recommendation": "Require a verified signature or strict role-based authorization before updating oracle state. If the oracle is not live yet, disable the entrypoint rather than accepting unauthenticated writes.",
    "exploit_scenario": "Any account can update `mainnetGasPrice` and `gasPriceTimestamp` by calling `setGasPrice`; the signature parameter is unused and the verification check is commented out. Today this state is not consumed elsewhere in first-party code, so impact is limited, but if operators or future upgrades rely on it, an attacker can feed arbitrary prices and timestamps."
}
info other cast Heavy EXTCODE*/BALANCE usage 55 no
view
evidence_json
{
    "notes": "frequent external code or balance checks; may indicate introspection or validation logic",
    "ext_balance_count": 8
}