ETH Price: $2,528.52 (-2.13%)

Transaction Decoder

Block:
21931597 at Feb-26-2025 04:07:11 PM +UTC
Transaction Fee:
0.000542660270222187 ETH $1.37
Gas Used:
160,563 Gas / 3.379734249 Gwei

Emitted Events:

304 WETH9.Deposit( dst=[Receiver] UniversalRouter, wad=3297856579313851 )
305 SoraToken.Transfer( from=0x7F63306A62C345365881e0fFF85CB2c8BaaA13D5, to=[Receiver] UniversalRouter, value=2005000000000000000000000000000 )
306 WETH9.Transfer( src=[Receiver] UniversalRouter, dst=0x7F63306A62C345365881e0fFF85CB2c8BaaA13D5, wad=3281449332650599 )
307 0x7f63306a62c345365881e0fff85cb2c8baaa13d5.0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67( 0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67, 0x0000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fad, 0x0000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fad, ffffffffffffffffffffffffffffffffffffffe6b17edf305403a2faf8000000, 000000000000000000000000000000000000000000000000000ba875f5d23267, 0000000000000000000000000000000000000000000000ad2cc3d794f9da5c50, 00000000000000000000000000000000000000000013cfa8998521082d2bf14d, fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffacdbe )
308 SoraToken.Transfer( from=[Receiver] UniversalRouter, to=FeeCollector, value=5000000000000000000000000000 )
309 SoraToken.Transfer( from=[Receiver] UniversalRouter, to=[Sender] 0x912efdf76db5d2b519029ecd3fd11552a8e6c271, value=2000000000000000000000000000000 )
310 WETH9.Withdrawal( src=[Receiver] UniversalRouter, wad=16407246663252 )

Account State Difference:

  Address   Before After State Difference Code
0x40FD7225...ce868F677
0x7F63306A...8BaaA13D5
(Uniswap V3: XOR 2)
0x912EFDf7...2A8e6C271
0.006901055275319522 Eth
Nonce: 130
0.003076945672446736 Eth
Nonce: 131
0.003824109602872786
(beaverbuild)
6.163296790702072078 Eth6.163617916702072078 Eth0.000321126
0xC02aaA39...83C756Cc2 2,937,792.121131705024867502 Eth2,937,792.124413154357518101 Eth0.003281449332650599

Execution Trace

ETH 0.003297856579313851 UniversalRouter.execute( commands=0x0B0105040C, inputs=[AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC7diEe4guw==, AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAGU6BIM+r/F0FCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALt2IR7iC7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAArQP1yJXWXqhTHIxp7Gqop/Oho9ncAJxDAKqo5siP+jQoOXE8n6tkIPHVswgAAAAAAAAAAAAAAAAAAAAAAAAAAAA==, AAAAAAAAAAAAAAAAQP1yJXWXqhTHIxp7Gqop/Oho9ncAAAAAAAAAAAAAAAAAAAD+4ToQOhDVk7muBrPgXy5+HAAAAAAAAAAAAAAAAAAAAAAAAAAAECfnLx8SgTCIAAAA, AAAAAAAAAAAAAAAAQP1yJXWXqhTHIxp7Gqop/Oho9ncAAAAAAAAAAAAAAACRLv33bbXStRkCns0/0RVSqObCcQAAAAAAAAAAAAAAAAAAAAAAAAAZPlk5oIzp29SAAAAA, AAAAAAAAAAAAAAAAkS7992210rUZAp7NP9EVUqjmwnEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==], deadline=1740587827 )
  • ETH 0.003297856579313851 WETH9.CALL( )
  • Uniswap V3: XOR 2.128acb08( )
    • SoraToken.transfer( to=0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD, value=2005000000000000000000000000000 ) => ( True )
    • WETH9.balanceOf( 0x7F63306A62C345365881e0fFF85CB2c8BaaA13D5 ) => ( 1560367785574204052 )
    • UniversalRouter.uniswapV3SwapCallback( amount0Delta=-2005000000000000000000000000000, amount1Delta=3281449332650599, data=0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000003FC91A3AFD70395CD496C647D5A6CC9D4B2B7FAD000000000000000000000000000000000000000000000000000000000000002B40FD72257597AA14C7231A7B1AAA29FCE868F677002710C02AAA39B223FE8D0A0E5C4F27EAD9083C756CC2000000000000000000000000000000000000000000 )
      • WETH9.transfer( dst=0x7F63306A62C345365881e0fFF85CB2c8BaaA13D5, wad=3281449332650599 ) => ( True )
      • WETH9.balanceOf( 0x7F63306A62C345365881e0fFF85CB2c8BaaA13D5 ) => ( 1563649234906854651 )
      • SoraToken.transfer( to=0x000000fee13a103A10D593b9AE06b3e05F2E7E1c, value=5000000000000000000000000000 ) => ( True )
      • SoraToken.balanceOf( owner=0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD ) => ( 2000000000000000000000000000000 )
      • SoraToken.transfer( to=0x912EFDf76db5D2b519029ecd3FD11552A8e6C271, value=2000000000000000000000000000000 ) => ( True )
      • WETH9.balanceOf( 0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD ) => ( 16407246663252 )
      • WETH9.withdraw( wad=16407246663252 )
        • ETH 0.000016407246663252 UniversalRouter.CALL( )
        • ETH 0.000016407246663252 0x912efdf76db5d2b519029ecd3fd11552a8e6c271.CALL( )
          File 1 of 4: UniversalRouter
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          // SPDX-License-Identifier: GPL-3.0-or-later
          pragma solidity ^0.8.17;
          // Command implementations
          import {Dispatcher} from './base/Dispatcher.sol';
          import {RewardsCollector} from './base/RewardsCollector.sol';
          import {RouterParameters, RouterImmutables} from './base/RouterImmutables.sol';
          import {Commands} from './libraries/Commands.sol';
          import {IUniversalRouter} from './interfaces/IUniversalRouter.sol';
          contract UniversalRouter is RouterImmutables, IUniversalRouter, Dispatcher, RewardsCollector {
          modifier checkDeadline(uint256 deadline) {
          if (block.timestamp > deadline) revert TransactionDeadlinePassed();
          _;
          }
          constructor(RouterParameters memory params) RouterImmutables(params) {}
          /// @inheritdoc IUniversalRouter
          function execute(bytes calldata commands, bytes[] calldata inputs, uint256 deadline)
          XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

          File 2 of 4: WETH9
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          // Copyright (C) 2015, 2016, 2017 Dapphub
          // This program is free software: you can redistribute it and/or modify
          // it under the terms of the GNU General Public License as published by
          // the Free Software Foundation, either version 3 of the License, or
          // (at your option) any later version.
          // This program 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 General Public License for more details.
          // You should have received a copy of the GNU General Public License
          // along with this program. If not, see <http://www.gnu.org/licenses/>.
          pragma solidity ^0.4.18;
          XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

          File 3 of 4: SoraToken
          1
          {"BasicToken.sol":{"content":"//! The basic-coin ECR20-compliant token contract.\n//!\n//! Copyright 2016 Gavin Wood, Parity Technologies Ltd.\n//!\n
              //! Licensed under the Apache License, Version 2.0 (the \"License\");\n//! you may not use this file except in compliance with the License.\n//!
              You may obtain a copy of the License at\n//!\n//! http://www.apache.org/licenses/LICENSE-2.0\n//!\n//! Unless required by applicable law or
              agreed to in writing, software\n//! distributed under the License is distributed on an \"AS IS\" BASIS,\n//! WITHOUT WARRANTIES OR CONDITIONS OF
              ANY KIND, either express or implied.\n//! See the License for the specific language governing permissions and\n//! limitations under the License
              .\n\npragma solidity ^0.5.8;\n\ncontract Owned {\n\tmodifier only_owner { require(msg.sender == owner); _; }\n\n\tevent NewOwner(address indexed
              old, address indexed current);\n\n function setOwner(address _new) only_owner public { emit NewOwner(owner, _new); owner = _new; }\n\n\taddress
              public owner = msg.sender;\n}\n\ninterface Token {\n\tevent Transfer(address indexed from, address indexed to, uint256 value);\n\tevent Approval
              (address indexed owner, address indexed spender, uint256 value);\n\n\tfunction balanceOf(address _owner) view external returns (uint256 balance
              );\n\tfunction transfer(address _to, uint256 _value) external returns (bool success);\n\tfunction transferFrom(address _from, address _to, uint256
              _value) external returns (bool success);\n\tfunction approve(address _spender, uint256 _value) external returns (bool success);\n\tfunction
              allowance(address _owner, address _spender) view external returns (uint256 remaining);\n}\n\n// TokenReg interface\ncontract TokenReg {\n\tfunction
              register(address _addr, string memory _tla, uint _base, string memory _name) public payable returns (bool);\n\tfunction registerAs(address _addr,
              string memory _tla, uint _base, string memory _name, address _owner) public payable returns (bool);\n\tfunction unregister(uint _id) public
              ;\n\tfunction setFee(uint _fee) public;\n\tfunction tokenCount() public view returns (uint);\n\tfunction token(uint _id) public view returns
              (address addr, string memory tla, uint base, string memory name, address owner);\n\tfunction fromAddress(address _addr) public view returns (uint
              id, string memory tla, uint base, string memory name, address owner);\n\tfunction fromTLA(string memory _tla) public view returns (uint id, address
              addr, uint base, string memory name, address owner);\n\tfunction meta(uint _id, bytes32 _key) public view returns (bytes32);\n\tfunction setMeta
              (uint _id, bytes32 _key, bytes32 _value) public;\n\tfunction drain() public;\n\tuint public fee;\n}\n\n// BasicCoin, ECR20 tokens that all belong
              to the owner for sending around\ncontract BasicCoin is Owned, Token {\n\t// this is as basic as can be, only the associated balance \u0026
              allowances\n\tstruct Account {\n\t\tuint balance;\n\t\tmapping (address =\u003e uint) allowanceOf;\n\t}\n\n\t// the balance should be
              available\n\tmodifier when_owns(address _owner, uint _amount) {\n\t\tif (accounts[_owner].balance \u003c _amount) revert();\n\t\t_;\n\t}\n\n\t// an
              allowance should be available\n\tmodifier when_has_allowance(address _owner, address _spender, uint _amount) {\n\t\tif (accounts[_owner]
              .allowanceOf[_spender] \u003c _amount) revert();\n\t\t_;\n\t}\n\n\n\n\t// a value should be \u003e 0\n\tmodifier when_non_zero(uint _value)
              {\n\t\tif (_value == 0) revert();\n\t\t_;\n\t}\n\n\tbool public called = false;\n\n\t// the base, tokens denoted in micros\n\tuint constant public
              base = 1000000;\n\n\t// available token supply\n\tuint public totalSupply;\n\n\t// storage and mapping of all balances \u0026 allowances\n\tmapping
              (address =\u003e Account) accounts;\n\n\t// constructor sets the parameters of execution, _totalSupply is all units\n\tconstructor(uint
              _totalSupply, address _owner) public when_non_zero(_totalSupply) {\n\t\ttotalSupply = _totalSupply;\n\t\towner = _owner;\n\t\taccounts[_owner]
              .balance = totalSupply;\n\t}\n\n\t// balance of a specific address\n\tfunction balanceOf(address _who) public view returns (uint256) {\n\t\treturn
              accounts[_who].balance;\n\t}\n\n\t// transfer\n\tfunction transfer(address _to, uint256 _value) public when_owns(msg.sender, _value) returns
              (bool) {\n\t\temit Transfer(msg.sender, _to, _value);\n\t\taccounts[msg.sender].balance -= _value;\n\t\taccounts[_to].balance += _value
              ;\n\n\t\treturn true;\n\t}\n\n\t// transfer via allowance\n\tfunction transferFrom(address _from, address _to, uint256 _value) public when_owns
              (_from, _value) when_has_allowance(_from, msg.sender, _value) returns (bool) {\n\t\tcalled = true;\n\t\temit Transfer(_from, _to, _value
              );\n\t\taccounts[_from].allowanceOf[msg.sender] -= _value;\n\t\taccounts[_from].balance -= _value;\n\t\taccounts[_to].balance += _value
              ;\n\n\t\treturn true;\n\t}\n\n\t// approve allowances\n\tfunction approve(address _spender, uint256 _value) public returns (bool) {\n\t\temit
              Approval(msg.sender, _spender, _value);\n\t\taccounts[msg.sender].allowanceOf[_spender] += _value;\n\n\t\treturn true;\n\t}\n\n\t// available
              allowance\n\tfunction allowance(address _owner, address _spender) public view returns (uint256) {\n\t\treturn accounts[_owner]
              .allowanceOf[_spender];\n\t}\n\n\t// no default function, simple contract only, entry-level users\n\tfunction() external {\n\t\trevert
              ();\n\t}\n}\n\n// Manages BasicCoin instances, including the deployment \u0026 registration\ncontract BasicCoinManager is Owned {\n\t// a structure
              wrapping a deployed BasicCoin\n\tstruct Coin {\n\t\taddress coin;\n\t\taddress owner;\n\t\taddress tokenreg;\n\t}\n\n\t// a new BasicCoin has been
              deployed\n\tevent Created(address indexed owner, address indexed tokenreg, address indexed coin);\n\n\t// a list of all the deployed
              BasicCoins\n\tCoin[] coins;\n\n\t// all BasicCoins for a specific owner\n\tmapping (address =\u003e uint[]) ownedCoins;\n\n\t// the base, tokens
              denoted in micros (matches up with BasicCoin interface above)\n\tuint constant public base = 1000000;\n\n\t// return the number of
              deployed\n\tfunction count() public view returns (uint) {\n\t\treturn coins.length;\n\t}\n\n\t// get a specific deployment\n\tfunction get(uint
              _index) public view returns (address coin, address owner, address tokenreg) {\n\t\tCoin memory c = coins[_index];\n\n\t\tcoin = c.coin;\n\t\towner
              = c.owner;\n\t\ttokenreg = c.tokenreg;\n\t}\n\n\t// returns the number of coins for a specific owner\n\tfunction countByOwner(address _owner)
              public view returns (uint) {\n\t\treturn ownedCoins[_owner].length;\n\t}\n\n\t// returns a specific index by owner\n\tfunction getByOwner(address
              _owner, uint _index) public view returns (address coin, address owner, address tokenreg) {\n\t\treturn get(ownedCoins[_owner][_index]);\n\t}\n\n\t
              // deploy a new BasicCoin on the blockchain\n\tfunction deploy(uint _totalSupply, string memory _tla, string memory _name, address _tokenreg)
              public payable returns (bool) {\n\t\tTokenReg tokenreg = TokenReg(_tokenreg);\n\t\tBasicCoin coin = new BasicCoin(_totalSupply, msg.sender
              );\n\n\t\tuint ownerCount = countByOwner(msg.sender);\n\t\tuint fee = tokenreg.fee();\n\n\t\townedCoins[msg.sender].length = ownerCount + 1
              ;\n\t\townedCoins[msg.sender][ownerCount] = coins.length;\n\t\tcoins.push(Coin(address(coin), msg.sender, address(tokenreg)));\n\t\ttokenreg
              .registerAs.value(fee)(address(coin), _tla, base, _name, msg.sender);\n\n\t\temit Created(msg.sender, address(tokenreg), address(coin
              ));\n\n\t\treturn true;\n\t}\n\n\t// owner can withdraw all collected funds\n\tfunction drain() public only_owner {\n\t\tif (!msg.sender.send
              (address(this).balance)) {\n\t\t\trevert();\n\t\t}\n\t}\n}\n"},"ERC20.sol":{"content":"pragma solidity ^0.5.8;\n\nimport \"./IERC20.sol\";\nimport
              \"./SafeMath.sol\";\n\n/**\n * @title Standard ERC20 token\n *\n * @dev Implementation of the basic standard token.\n * https://github.com/ethereum
              /EIPs/blob/master/EIPS/eip-20.md\n * Originally based on code by FirstBlood:\n * https://github.com/Firstbloodio/token/blob/master/smart_contract
              /FirstBloodToken.sol\n *\n * This implementation emits additional Approval events, allowing applications to reconstruct the allowance status for\n
              * all accounts just by listening to said events. Note that this isn\u0027t required by the specification, and other\n * compliant implementations
              may not do it.\n */\ncontract ERC20 is IERC20 {\n using SafeMath for uint256;\n\n mapping(address =\u003e uint256) private _balances;\n\n
              mapping(address =\u003e mapping(address =\u003e uint256)) private _allowed;\n\n uint256 private _totalSupply;\n\n /**\n * @dev Total
              number of tokens in existence\n */\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n /**\n
               * @dev Gets the balance of the specified address.\n * @param owner The address to query the balance of.\n * @return An uint256
              representing the amount owned by the passed address.\n */\n function balanceOf(address owner) public view returns (uint256) {\n return
              _balances[owner];\n }\n\n /**\n * @dev Function to check the amount of tokens that an owner allowed to a spender.\n * @param owner
              address The address which owns the funds.\n * @param spender address The address which will spend the funds.\n * @return A uint256
              specifying the amount of tokens still available for the spender.\n */\n function allowance(address owner, address spender) public view
              returns (uint256) {\n return _allowed[owner][spender];\n }\n\n /**\n * @dev Transfer token for a specified address\n * @param to
              The address to transfer to.\n * @param value The amount to be transferred.\n */\n function transfer(address to, uint256 value) public
              returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n /**\n * @dev Approve the passed address to
              spend the specified amount of tokens on behalf of msg.sender.\n * Beware that changing an allowance with this method brings the risk that
              someone may use both the old\n * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this\n * race
              condition is to first reduce the spender\u0027s allowance to 0 and set the desired value afterwards:\n * https://github.com/ethereum/EIPs
              /issues/20#issuecomment-263524729\n * @param spender The address which will spend the funds.\n * @param value The amount of tokens to be
              spent.\n */\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n
               return true;\n }\n\n /**\n * @dev Transfer tokens from one address to another.\n * Note that while this function emits an Approval
              event, this is not required as per the specification,\n * and other compliant implementations may not emit the event.\n * @param from
              address The address which you want to send tokens from\n * @param to address The address which you want to transfer to\n * @param value
              uint256 the amount of tokens to be transferred\n */\n function transferFrom(address from, address to, uint256 value) public returns (bool)
              {\n _transfer(from, to, value);\n _approve(from, msg.sender, _allowed[from][msg.sender].sub(value));\n return true;\n }\n\n
               /**\n * @dev Increase the amount of tokens that an owner allowed to a spender.\n * approve should be called when allowed_[_spender] == 0
              . To increment\n * allowed value is better to use this function to avoid 2 calls (and wait until\n * the first transaction is mined)\n
              * From MonolithDAO Token.sol\n * Emits an Approval event.\n * @param spender The address which will spend the funds.\n * @param
              addedValue The amount of tokens to increase the allowance by.\n */\n function increaseAllowance(address spender, uint256 addedValue) public
              returns (bool) {\n _approve(msg.sender, spender, _allowed[msg.sender][spender].add(addedValue));\n return true;\n }\n\n /**\n
               * @dev Decrease the amount of tokens that an owner allowed to a spender.\n * approve should be called when allowed_[_spender] == 0. To
              decrement\n * allowed value is better to use this function to avoid 2 calls (and wait until\n * the first transaction is mined)\n *
              From MonolithDAO Token.sol\n * Emits an Approval event.\n * @param spender The address which will spend the funds.\n * @param
              subtractedValue The amount of tokens to decrease the allowance by.\n */\n function decreaseAllowance(address spender, uint256
              subtractedValue) public returns (bool) {\n _approve(msg.sender, spender, _allowed[msg.sender][spender].sub(subtractedValue));\n
              return true;\n }\n\n /**\n * @dev Transfer token for a specified addresses\n * @param from The address to transfer from.\n * @param
              to The address to transfer to.\n * @param value The amount to be transferred.\n */\n function _transfer(address from, address to, uint256
              value) internal {\n require(to != address(0));\n\n _balances[from] = _balances[from].sub(value);\n _balances[to] =
              _balances[to].add(value);\n emit Transfer(from, to, value);\n }\n\n /**\n * @dev Internal function that mints an amount of the
              token and assigns it to\n * an account. This encapsulates the modification of balances such that the\n * proper events are emitted.\n *
              @param account The account that will receive the created tokens.\n * @param value The amount that will be created.\n */\n function _mint
              (address account, uint256 value) internal {\n require(account != address(0));\n\n _totalSupply = _totalSupply.add(value);\n
              _balances[account] = _balances[account].add(value);\n emit Transfer(address(0), account, value);\n }\n\n /**\n * @dev Internal
              function that burns an amount of the token of a given\n * account.\n * @param account The account whose tokens will be burnt.\n *
              @param value The amount that will be burnt.\n */\n function _burn(address account, uint256 value) internal {\n require(account !=
              address(0));\n\n _totalSupply = _totalSupply.sub(value);\n _balances[account] = _balances[account].sub(value);\n emit Transfer
              (account, address(0), value);\n }\n\n /**\n * @dev Approve an address to spend another addresses\u0027 tokens.\n * @param owner The
              address that owns the tokens.\n * @param spender The address that will spend the tokens.\n * @param value The number of tokens that can be
              spent.\n */\n function _approve(address owner, address spender, uint256 value) internal {\n require(spender != address(0));\n
              require(owner != address(0));\n\n _allowed[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n /**\n *
              @dev Internal function that burns an amount of the token of a given\n * account, deducting from the sender\u0027s allowance for said account.
              Uses the\n * internal burn function.\n * Emits an Approval event (reflecting the reduced allowance).\n * @param account The account
              whose tokens will be burnt.\n * @param value The amount that will be burnt.\n */\n function _burnFrom(address account, uint256 value)
              internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowed[account][msg.sender].sub(value));\n }\n}\n"}
              ,"ERC20Burnable.sol":{"content":"pragma solidity ^0.5.8;\n\nimport \"./ERC20.sol\";\n\n/**\n * @title Burnable Token\n * @dev Token that can be
              irreversibly burned (destroyed).\n */\ncontract ERC20Burnable is ERC20 {\n /**\n * @dev Burns a specific amount of tokens.\n * @param
              value The amount of token to be burned.\n */\n function burn(uint256 value) public {\n _burn(msg.sender, value);\n }\n\n /**\n
               * @dev Burns a specific amount of tokens from the target address and decrements allowance\n * @param from address The address which you
              want to send tokens from\n * @param value uint256 The amount of token to be burned\n */\n function burnFrom(address from, uint256 value)
              public {\n _burnFrom(from, value);\n }\n}\n"},"ERC20Detailed.sol":{"content":"pragma solidity ^0.5.8;\n\nimport \"./IERC20.sol\";\n\n
              /**\n * @title ERC20Detailed token\n * @dev The decimals are only for visualization purposes.\n * All the operations are done using the smallest
              and indivisible token unit,\n * just as on Ethereum all the operations are done in wei.\n */\ncontract ERC20Detailed is IERC20 {\n string
              private _name;\n string private _symbol;\n uint8 private _decimals;\n\n constructor (string memory name, string memory symbol, uint8
              decimals) public {\n _name = name;\n _symbol = symbol;\n _decimals = decimals;\n }\n\n /**\n * @return the name of
              the token.\n */\n function name() public view returns (string memory) {\n return _name;\n }\n\n /**\n * @return the symbol
              of the token.\n */\n function symbol() public view returns (string memory) {\n return _symbol;\n }\n\n /**\n * @return the
              number of decimals of the token.\n */\n function decimals() public view returns (uint8) {\n return _decimals;\n }\n}\n"},"Failer
              .sol":{"content":"pragma solidity ^0.5.8;\n\n/**\n * Contract for revert cases testing\n */\ncontract Failer {\n /**\n * A special function
              -like stub to allow ether accepting. Always fails.\n */\n function() external payable {\n revert(\"eth transfer revert\");\n }\n\n
               /**\n * Fake ERC-20 transfer function. Always fails.\n */\n function transfer(address, uint256) external pure {\n revert(\"ERC
              -20 transfer revert\");\n }\n}\n"},"IERC20.sol":{"content":"pragma solidity ^0.5.8;\n\n/**\n * @title ERC20 interface\n * @dev see https
              ://github.com/ethereum/EIPs/issues/20\n */\ninterface IERC20 {\n function transfer(address to, uint256 value) external returns (bool);\n\n
              function approve(address spender, uint256 value) external returns (bool);\n\n function transferFrom(address from, address to, uint256 value)
              external returns (bool);\n\n function totalSupply() external view returns (uint256);\n\n function balanceOf(address who) external view
              returns (uint256);\n\n function allowance(address owner, address spender) external view returns (uint256);\n\n event Transfer(address indexed
              from, address indexed to, uint256 value);\n\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"},"IMaster
              .sol":{"content":"pragma solidity ^0.5.8;\n\n/**\n * Subset of master contract interface\n */\ncontract IMaster {\n function withdraw(\n
              address tokenAddress,\n uint256 amount,\n address to,\n bytes32 txHash,\n uint8[] memory v,\n bytes32[] memory r
              ,\n bytes32[] memory s,\n address from\n )\n public;\n\n function mintTokensByPeers(\n address tokenAddress,\n
               uint256 amount,\n address beneficiary,\n bytes32 txHash,\n uint8[] memory v,\n bytes32[] memory r,\n bytes32[]
              memory s,\n address from\n )\n public;\n\n function checkTokenAddress(address token) public view returns (bool);\n}\n"}
              ,"IRelayRegistry.sol":{"content":"pragma solidity ^0.5.8;\n\n/**\n * @title Relay registry interface\n */\ninterface IRelayRegistry {\n\n /**\n
               * Store relay address and appropriate whitelist of addresses\n * @param relay contract address\n * @param whiteList with allowed
              addresses\n * @return true if data was stored\n */\n function addNewRelayAddress(address relay, address[] calldata whiteList) external
              ;\n\n /**\n * Check if some address is in the whitelist\n * @param relay contract address\n * @param who address in whitelist\n
              * @return true if address in the whitelist\n */\n function isWhiteListed(address relay, address who) external view returns (bool);\n\n
              /**\n * Get entire whitelist by relay address\n * @param relay contract address\n * @return array of the whitelist\n */\n
              function getWhiteListByRelay(address relay) external view returns (address[] memory);\n\n event AddNewRelay (\n address indexed
              relayAddress,\n address[] indexed whiteList\n );\n}\n"},"Master.sol":{"content":"pragma solidity ^0.5.8;\n\nimport \"./IERC20.sol\"
              ;\nimport \"./SoraToken.sol\";\n\n/**\n * Provides functionality of master contract\n */\ncontract Master {\n bool internal initialized_;\n
              address public owner_;\n mapping(address =\u003e bool) public isPeer;\n uint public peersCount;\n /** Iroha tx hashes used */\n mapping
              (bytes32 =\u003e bool) public used;\n mapping(address =\u003e bool) public uniqueAddresses;\n\n /** registered client addresses */\n
              mapping(address =\u003e bytes) public registeredClients;\n\n SoraToken public xorTokenInstance;\n\n mapping(address =\u003e bool) public
              isToken;\n\n /**\n * Emit event on new registration with iroha acountId\n */\n event IrohaAccountRegistration(address
              ethereumAddress, bytes accountId);\n\n /**\n * Emit event when master contract does not have enough assets to proceed withdraw\n */\n
               event InsufficientFundsForWithdrawal(address asset, address recipient);\n\n /**\n * Constructor. Sets contract owner to contract creator.\n
               */\n constructor(address[] memory initialPeers) public {\n initialize(msg.sender, initialPeers);\n }\n\n /**\n *
              Initialization of smart contract.\n */\n function initialize(address owner, address[] memory initialPeers) public {\n require
              (!initialized_);\n\n owner_ = owner;\n for (uint8 i = 0; i \u003c initialPeers.length; i++) {\n addPeer(initialPeers[i]
              );\n }\n\n // 0 means ether which is definitely in whitelist\n isToken[address(0)] = true;\n\n // Create new instance
              of Sora token\n xorTokenInstance = new SoraToken();\n isToken[address(xorTokenInstance)] = true;\n\n initialized_ = true;\n
               }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(isOwner
              ());\n _;\n }\n\n /**\n * @return true if `msg.sender` is the owner of the contract.\n */\n function isOwner() public view
              returns(bool) {\n return msg.sender == owner_;\n }\n\n /**\n * A special function-like stub to allow ether accepting\n */\n
               function() external payable {\n require(msg.data.length == 0);\n }\n\n /**\n * Adds new peer to list of signature verifiers. Can
              be called only by contract owner.\n * @param newAddress address of new peer\n */\n function addPeer(address newAddress) private returns
              (uint) {\n require(isPeer[newAddress] == false);\n isPeer[newAddress] = true;\n ++peersCount;\n return peersCount;\n
               }\n\n function removePeer(address peerAddress) private {\n require(isPeer[peerAddress] == true);\n isPeer[peerAddress] = false;\n
               --peersCount;\n }\n\n function addPeerByPeer(\n address newPeerAddress,\n bytes32 txHash,\n uint8[] memory v,\n
               bytes32[] memory r,\n bytes32[] memory s\n )\n public returns (bool)\n {\n require(used[txHash] == false);\n
              require(checkSignatures(keccak256(abi.encodePacked(newPeerAddress, txHash)),\n v,\n r,\n s)\n );\n\n
               addPeer(newPeerAddress);\n used[txHash] = true;\n return true;\n }\n\n function removePeerByPeer(\n address peerAddress
              ,\n bytes32 txHash,\n uint8[] memory v,\n bytes32[] memory r,\n bytes32[] memory s\n )\n public returns (bool)\n
               {\n require(used[txHash] == false);\n require(checkSignatures(\n keccak256(abi.encodePacked(peerAddress, txHash)),\n
               v,\n r,\n s)\n );\n\n removePeer(peerAddress);\n used[txHash] = true;\n return true;\n
               }\n\n /**\n * Adds new token to whitelist. Token should not been already added.\n * @param newToken token to add\n */\n
              function addToken(address newToken) public onlyOwner {\n require(isToken[newToken] == false);\n isToken[newToken] = true;\n }\n\n
               /**\n * Checks is given token inside a whitelist or not\n * @param tokenAddress address of token to check\n * @return true if token
              inside whitelist or false otherwise\n */\n function checkTokenAddress(address tokenAddress) public view returns (bool) {\n return
              isToken[tokenAddress];\n }\n\n /**\n * Register a clientIrohaAccountId for the caller clientEthereumAddress\n * @param
              clientEthereumAddress - ethereum address to register\n * @param clientIrohaAccountId - iroha account id\n * @param txHash - iroha tx hash
              of registration\n * @param v array of signatures of tx_hash (v-component)\n * @param r array of signatures of tx_hash (r-component)\n *
              @param s array of signatures of tx_hash (s-component)\n */\n function register(\n address clientEthereumAddress,\n bytes
              memory clientIrohaAccountId,\n bytes32 txHash,\n uint8[] memory v,\n bytes32[] memory r,\n bytes32[] memory s\n )\n
               public\n {\n require(used[txHash] == false);\n require(checkSignatures(\n keccak256(abi.encodePacked
              (clientEthereumAddress, clientIrohaAccountId, txHash)),\n v,\n r,\n s)\n
              );\n require(clientEthereumAddress == msg.sender);\n require(registeredClients[clientEthereumAddress].length == 0);\n\n
              registeredClients[clientEthereumAddress] = clientIrohaAccountId;\n\n emit IrohaAccountRegistration(clientEthereumAddress,
              clientIrohaAccountId);\n }\n\n /**\n * Withdraws specified amount of ether or one of ERC-20 tokens to provided address\n * @param
              tokenAddress address of token to withdraw (0 for ether)\n * @param amount amount of tokens or ether to withdraw\n * @param to target
              account address\n * @param txHash hash of transaction from Iroha\n * @param v array of signatures of tx_hash (v-component)\n * @param r
              array of signatures of tx_hash (r-component)\n * @param s array of signatures of tx_hash (s-component)\n * @param from relay contract
              address\n */\n function withdraw(\n address tokenAddress,\n uint256 amount,\n address payable to,\n bytes32
              txHash,\n uint8[] memory v,\n bytes32[] memory r,\n bytes32[] memory s,\n address from\n )\n public\n {\n
               require(checkTokenAddress(tokenAddress));\n require(used[txHash] == false);\n require(checkSignatures(\n keccak256(abi
              .encodePacked(tokenAddress, amount, to, txHash, from)),\n v,\n r,\n s)\n );\n\n if (tokenAddress ==
              address (0)) {\n if (address(this).balance \u003c amount) {\n emit InsufficientFundsForWithdrawal(tokenAddress, to);\n
               } else {\n used[txHash] = true;\n // untrusted transfer, relies on provided cryptographic proof\n
               to.transfer(amount);\n }\n } else {\n IERC20 coin = IERC20(tokenAddress);\n if (coin.balanceOf(address
              (this)) \u003c amount) {\n emit InsufficientFundsForWithdrawal(tokenAddress, to);\n } else {\n
              used[txHash] = true;\n // untrusted call, relies on provided cryptographic proof\n coin.transfer(to, amount);\n
               }\n }\n }\n\n /**\n * Checks given addresses for duplicates and if they are peers signatures\n * @param hash unsigned
              data\n * @param v v-component of signature from hash\n * @param r r-component of signature from hash\n * @param s s-component of
              signature from hash\n * @return true if all given addresses are correct or false otherwise\n */\n function checkSignatures(bytes32 hash
              ,\n uint8[] memory v,\n bytes32[] memory r,\n bytes32[] memory s\n ) private returns (bool) {\n require(peersCount
              \u003e= 1);\n require(v.length == r.length);\n require(r.length == s.length);\n uint needSigs = peersCount - (peersCount - 1)
              / 3;\n require(s.length \u003e= needSigs);\n\n uint count = 0;\n address[] memory recoveredAddresses = new address[](s.length
              );\n for (uint i = 0; i \u003c s.length; ++i) {\n address recoveredAddress = recoverAddress(\n hash,\n
               v[i],\n r[i],\n s[i]\n );\n\n // not a peer address or not unique\n if
              (isPeer[recoveredAddress] != true || uniqueAddresses[recoveredAddress] == true) {\n continue;\n }\n
              recoveredAddresses[count] = recoveredAddress;\n count = count + 1;\n uniqueAddresses[recoveredAddress] = true;\n }\n\n
               // restore state for future usages\n for (uint i = 0; i \u003c count; ++i) {\n uniqueAddresses[recoveredAddresses[i]] =
              false;\n }\n\n return count \u003e= needSigs;\n }\n\n /**\n * Recovers address from a given single signature\n * @param
              hash unsigned data\n * @param v v-component of signature from hash\n * @param r r-component of signature from hash\n * @param s s
              -component of signature from hash\n * @return address recovered from signature\n */\n function recoverAddress(bytes32 hash, uint8 v,
              bytes32 r, bytes32 s) private pure returns (address) {\n bytes32 simple_hash = keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message
              :\\n32\", hash));\n address res = ecrecover(simple_hash, v, r, s);\n return res;\n }\n\n /**\n * Mint new XORToken\n *
              @param tokenAddress address to mint\n * @param amount how much to mint\n * @param beneficiary destination address\n * @param txHash
              hash of transaction from Iroha\n * @param v array of signatures of tx_hash (v-component)\n * @param r array of signatures of tx_hash (r
              -component)\n * @param s array of signatures of tx_hash (s-component)\n */\n function mintTokensByPeers(\n address tokenAddress
              ,\n uint256 amount,\n address beneficiary,\n bytes32 txHash,\n uint8[] memory v,\n bytes32[] memory r,\n
              bytes32[] memory s,\n address from\n )\n public\n {\n require(address(xorTokenInstance) == tokenAddress);\n require
              (used[txHash] == false);\n require(checkSignatures(\n keccak256(abi.encodePacked(tokenAddress, amount, beneficiary, txHash, from
              )),\n v,\n r,\n s)\n );\n\n xorTokenInstance.mintTokens(beneficiary, amount);\n used[txHash]
              = true;\n }\n}\n"},"MasterRelayed.sol":{"content":"pragma solidity ^0.5.8;\n\nimport \"./IRelayRegistry.sol\";\nimport \"./IERC20.sol\";\nimport
              \"./SoraToken.sol\";\n\n/**\n * Provides functionality of master contract with relays\n */\ncontract MasterRelayed {\n bool internal
              initialized_;\n address public owner_;\n mapping(address =\u003e bool) public isPeer;\n /** Iroha tx hashes used */\n uint public
              peersCount;\n mapping(bytes32 =\u003e bool) public used;\n mapping(address =\u003e bool) public uniqueAddresses;\n\n /** registered client
              addresses */\n address public relayRegistryAddress;\n IRelayRegistry public relayRegistryInstance;\n\n SoraToken public xorTokenInstance
              ;\n\n mapping(address =\u003e bool) public isToken;\n\n /**\n * Emit event when master contract does not have enough assets to proceed
              withdraw\n */\n event InsufficientFundsForWithdrawal(address asset, address recipient);\n\n /**\n * Constructor. Sets contract owner
              to contract creator.\n */\n constructor(address relayRegistry, address[] memory initialPeers) public {\n initialize(msg.sender,
              relayRegistry, initialPeers);\n }\n\n /**\n * Initialization of smart contract.\n */\n function initialize(address owner, address
              relayRegistry, address[] memory initialPeers) public {\n require(!initialized_);\n\n owner_ = owner;\n relayRegistryAddress =
              relayRegistry;\n relayRegistryInstance = IRelayRegistry(relayRegistryAddress);\n for (uint8 i = 0; i \u003c initialPeers.length; i++)
              {\n addPeer(initialPeers[i]);\n }\n\n // 0 means ether which is definitely in whitelist\n isToken[address(0)] =
              true;\n\n // Create new instance of Sora token\n xorTokenInstance = new SoraToken();\n isToken[address(xorTokenInstance)] =
              true;\n\n initialized_ = true;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier
              onlyOwner() {\n require(isOwner());\n _;\n }\n\n /**\n * @return true if `msg.sender` is the owner of the contract.\n
              */\n function isOwner() public view returns(bool) {\n return msg.sender == owner_;\n }\n\n /**\n * A special function-like stub
              to allow ether accepting\n */\n function() external payable {\n require(msg.data.length == 0);\n }\n\n /**\n * Adds new
              peer to list of signature verifiers. Can be called only by contract owner.\n * @param newAddress address of new peer\n */\n function
              addPeer(address newAddress) private returns (uint) {\n require(isPeer[newAddress] == false);\n isPeer[newAddress] = true;\n
              ++peersCount;\n return peersCount;\n }\n\n function removePeer(address peerAddress) private {\n require(isPeer[peerAddress] ==
              true);\n isPeer[peerAddress] = false;\n --peersCount;\n }\n\n function addPeerByPeer(\n address newPeerAddress,\n
               bytes32 txHash,\n uint8[] memory v,\n bytes32[] memory r,\n bytes32[] memory s\n )\n public returns (bool)\n {\n
               require(used[txHash] == false);\n require(checkSignatures(keccak256(abi.encodePacked(newPeerAddress, txHash)),\n v,\n
               r,\n s)\n );\n\n addPeer(newPeerAddress);\n used[txHash] = true;\n return true;\n }\n\n function
              removePeerByPeer(\n address peerAddress,\n bytes32 txHash,\n uint8[] memory v,\n bytes32[] memory r,\n bytes32[]
              memory s\n )\n public returns (bool)\n {\n require(used[txHash] == false);\n require(checkSignatures(\n keccak256
              (abi.encodePacked(peerAddress, txHash)),\n v,\n r,\n s)\n );\n\n removePeer(peerAddress);\n
              used[txHash] = true;\n return true;\n }\n\n /**\n * Adds new token to whitelist. Token should not been already added.\n *
              @param newToken token to add\n */\n function addToken(address newToken) public onlyOwner {\n require(isToken[newToken] == false);\n
               isToken[newToken] = true;\n }\n\n /**\n * Checks is given token inside a whitelist or not\n * @param tokenAddress address of
              token to check\n * @return true if token inside whitelist or false otherwise\n */\n function checkTokenAddress(address tokenAddress)
              public view returns (bool) {\n return isToken[tokenAddress];\n }\n\n /**\n * Withdraws specified amount of ether or one of ERC-20
              tokens to provided address\n * @param tokenAddress address of token to withdraw (0 for ether)\n * @param amount amount of tokens or ether
              to withdraw\n * @param to target account address\n * @param txHash hash of transaction from Iroha\n * @param v array of signatures of
              tx_hash (v-component)\n * @param r array of signatures of tx_hash (r-component)\n * @param s array of signatures of tx_hash (s-component)\n
               * @param from relay contract address\n */\n function withdraw(\n address tokenAddress,\n uint256 amount,\n address
              payable to,\n bytes32 txHash,\n uint8[] memory v,\n bytes32[] memory r,\n bytes32[] memory s,\n address from\n
               )\n public\n {\n require(checkTokenAddress(tokenAddress));\n require(relayRegistryInstance.isWhiteListed(from, to));\n
               require(used[txHash] == false);\n require(checkSignatures(\n keccak256(abi.encodePacked(tokenAddress, amount, to, txHash, from
              )),\n v,\n r,\n s)\n );\n\n if (tokenAddress == address (0)) {\n if (address(this
              ).balance \u003c amount) {\n emit InsufficientFundsForWithdrawal(tokenAddress, to);\n } else {\n
              used[txHash] = true;\n // untrusted transfer, relies on provided cryptographic proof\n to.transfer(amount);\n
               }\n } else {\n IERC20 coin = IERC20(tokenAddress);\n if (coin.balanceOf(address (this)) \u003c amount) {\n
               emit InsufficientFundsForWithdrawal(tokenAddress, to);\n } else {\n used[txHash] = true;\n //
              untrusted call, relies on provided cryptographic proof\n coin.transfer(to, amount);\n }\n }\n }\n\n /**\n
               * Checks given addresses for duplicates and if they are peers signatures\n * @param hash unsigned data\n * @param v v-component of
              signature from hash\n * @param r r-component of signature from hash\n * @param s s-component of signature from hash\n * @return true if
              all given addresses are correct or false otherwise\n */\n function checkSignatures(bytes32 hash,\n uint8[] memory v,\n
              bytes32[] memory r,\n bytes32[] memory s\n ) private returns (bool) {\n require(peersCount \u003e= 1);\n require(v.length
              == r.length);\n require(r.length == s.length);\n uint needSigs = peersCount - (peersCount - 1) / 3;\n require(s.length \u003e=
              needSigs);\n\n uint count = 0;\n address[] memory recoveredAddresses = new address[](s.length);\n for (uint i = 0; i \u003c s
              .length; ++i) {\n address recoveredAddress = recoverAddress(\n hash,\n v[i],\n r[i],\n
               s[i]\n );\n\n // not a peer address or not unique\n if (isPeer[recoveredAddress] != true ||
              uniqueAddresses[recoveredAddress] == true) {\n continue;\n }\n recoveredAddresses[count] = recoveredAddress;\n
               count = count + 1;\n uniqueAddresses[recoveredAddress] = true;\n }\n\n // restore state for future usages\n
               for (uint i = 0; i \u003c count; ++i) {\n uniqueAddresses[recoveredAddresses[i]] = false;\n }\n\n return count \u003e=
              needSigs;\n }\n\n /**\n * Recovers address from a given single signature\n * @param hash unsigned data\n * @param v v-component
              of signature from hash\n * @param r r-component of signature from hash\n * @param s s-component of signature from hash\n * @return
              address recovered from signature\n */\n function recoverAddress(bytes32 hash, uint8 v, bytes32 r, bytes32 s) private pure returns (address)
              {\n bytes32 simple_hash = keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n address res = ecrecover
              (simple_hash, v, r, s);\n return res;\n }\n\n /**\n * Mint new XORToken\n * @param tokenAddress address to mint\n * @param
              amount how much to mint\n * @param beneficiary destination address\n * @param txHash hash of transaction from Iroha\n * @param v array
              of signatures of tx_hash (v-component)\n * @param r array of signatures of tx_hash (r-component)\n * @param s array of signatures of
              tx_hash (s-component)\n */\n function mintTokensByPeers(\n address tokenAddress,\n uint256 amount,\n address
              beneficiary,\n bytes32 txHash,\n uint8[] memory v,\n bytes32[] memory r,\n bytes32[] memory s,\n address from\n
               )\n public\n {\n require(address(xorTokenInstance) == tokenAddress);\n require(relayRegistryInstance.isWhiteListed(from,
              beneficiary));\n require(used[txHash] == false);\n require(checkSignatures(\n keccak256(abi.encodePacked(tokenAddress,
              amount, beneficiary, txHash, from)),\n v,\n r,\n s)\n );\n\n xorTokenInstance.mintTokens(beneficiary
              , amount);\n used[txHash] = true;\n }\n}\n"},"Ownable.sol":{"content":"pragma solidity ^0.5.8;\n\n/**\n * @title Ownable\n * @dev The
              Ownable contract has an owner address, and provides basic authorization control\n * functions, this simplifies the implementation of \"user
              permissions\".\n */\ncontract Ownable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address
              indexed newOwner);\n\n /**\n * @dev The Ownable constructor sets the original `owner` of the contract to the sender\n * account.\n
              */\n constructor () internal {\n _owner = msg.sender;\n emit OwnershipTransferred(address(0), _owner);\n }\n\n /**\n *
              @return the address of the owner.\n */\n function owner() public view returns (address) {\n return _owner;\n }\n\n /**\n *
              @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(isOwner());\n _;\n }\n\n
               /**\n * @return true if `msg.sender` is the owner of the contract.\n */\n function isOwner() public view returns (bool) {\n
              return msg.sender == _owner;\n }\n\n /**\n * @dev Allows the current owner to relinquish control of the contract.\n * @notice
              Renouncing to ownership will leave the contract without an owner.\n * It will not be possible to call the functions with the `onlyOwner`\n
              * modifier anymore.\n */\n function renounceOwnership() public onlyOwner {\n emit OwnershipTransferred(_owner, address(0));\n
              _owner = address(0);\n }\n\n /**\n * @dev Allows the current owner to transfer control of the contract to a newOwner.\n * @param
              newOwner The address to transfer ownership to.\n */\n function transferOwnership(address newOwner) public onlyOwner {\n
              _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers control of the contract to a newOwner.\n * @param newOwner The address
              to transfer ownership to.\n */\n function _transferOwnership(address newOwner) internal {\n require(newOwner != address(0));\n
               emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n}\n"},"OwnedUpgradeabilityProxy.sol":{"content":"pragma solidity
              ^0.5.8;\n\nimport \u0027./UpgradeabilityProxy.sol\u0027;\n\n/**\n * @title OwnedUpgradeabilityProxy\n * @dev This contract combines an
              upgradeability proxy with basic authorization control functionalities\n */\ncontract OwnedUpgradeabilityProxy is UpgradeabilityProxy {\n /**\n *
              @dev Event to show ownership has been transferred\n * @param previousOwner representing the address of the previous owner\n * @param newOwner
              representing the address of the new owner\n */\n event ProxyOwnershipTransferred(address previousOwner, address newOwner);\n\n // Storage
              position of the owner of the contract\n bytes32 private constant proxyOwnerPosition = keccak256(\"com.d3ledger.proxy.owner\");\n\n /**\n * @dev
              the constructor sets the original owner of the contract to the sender account.\n */\n constructor() public {\n setUpgradeabilityOwner(msg
              .sender);\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyProxyOwner() {\n require(msg
              .sender == proxyOwner());\n _;\n }\n\n /**\n * @dev Tells the address of the owner\n * @return the address of the owner\n */\n function
              proxyOwner() public view returns (address owner) {\n bytes32 position = proxyOwnerPosition;\n assembly {\n owner := sload(position)\n
               }\n }\n\n /**\n * @dev Sets the address of the owner\n */\n function setUpgradeabilityOwner(address newProxyOwner) internal {\n bytes32
              position = proxyOwnerPosition;\n assembly {\n sstore(position, newProxyOwner)\n }\n }\n\n /**\n * @dev Allows the current owner to
              transfer control of the contract to a newOwner.\n * @param newOwner The address to transfer ownership to.\n */\n function
              transferProxyOwnership(address newOwner) public onlyProxyOwner {\n require(newOwner != address(0));\n emit ProxyOwnershipTransferred
              (proxyOwner(), newOwner);\n setUpgradeabilityOwner(newOwner);\n }\n\n /**\n * @dev Allows the proxy owner to upgrade the current version of
              the proxy.\n * @param implementation representing the address of the new implementation to be set.\n */\n function upgradeTo(address
              implementation) public onlyProxyOwner {\n _upgradeTo(implementation);\n }\n\n /**\n * @dev Allows the proxy owner to upgrade the current
              version of the proxy and call the new implementation\n * to initialize whatever is needed through a low level call.\n * @param implementation
              representing the address of the new implementation to be set.\n * @param data represents the msg.data to bet sent in the low level call. This
              parameter may include the function\n * signature of the implementation to be called with the needed payload\n */\n function upgradeToAndCall
              (address implementation, bytes memory data) payable public onlyProxyOwner {\n upgradeTo(implementation);\n (bool success,) = address(this
              ).call.value(msg.value)(data);\n require(success);\n }\n}\n"},"Proxy.sol":{"content":"pragma solidity ^0.5.8;\n\n/**\n * @title Proxy\n * @dev
              Gives the possibility to delegate any call to a foreign implementation.\n */\ncontract Proxy {\n /**\n * @dev Tells the address of the
              implementation where every call will be delegated.\n * @return address of the implementation to which it will be delegated\n */\n function
              implementation() public view returns (address);\n\n /**\n * @dev Fallback function allowing to perform a delegatecall to the given implementation
              .\n * This function will return whatever the implementation call returns\n */\n function () payable external {\n address _impl =
              implementation();\n require(_impl != address(0));\n\n assembly {\n let ptr := mload(0x40)\n calldatacopy(ptr, 0, calldatasize)\n
               let result := delegatecall(gas, _impl, ptr, calldatasize, 0, 0)\n let size := returndatasize\n returndatacopy(ptr, 0, size)\n\n
              switch result\n case 0 { revert(ptr, size) }\n default { return(ptr, size) }\n }\n }\n}\n"},"Relay.sol":{"content":"pragma solidity
              ^0.5.8;\n\nimport \"./IMaster.sol\";\nimport \"./IERC20.sol\";\n\n/**\n * Provides functionality of relay contract\n */\ncontract Relay {\n bool
              internal initialized_;\n address payable private masterAddress;\n IMaster private masterInstance;\n\n event AddressEvent(address input);\n
               event StringEvent(string input);\n event BytesEvent(bytes32 input);\n event NumberEvent(uint256 input);\n\n /**\n * Relay
              constructor\n * @param master address of master contract\n */\n constructor(address payable master) public {\n initialize(master
              );\n }\n\n /**\n * Initialization of smart contract.\n */\n function initialize(address payable master) public {\n require
              (!initialized_);\n masterAddress = master;\n masterInstance = IMaster(masterAddress);\n initialized_ = true;\n }\n\n
              /**\n * A special function-like stub to allow ether accepting\n */\n function() external payable {\n require(msg.data.length == 0
              );\n emit AddressEvent(msg.sender);\n }\n\n /**\n * Sends ether and all tokens from this contract to master\n * @param
              tokenAddress address of sending token (0 for Ether)\n */\n function sendToMaster(address tokenAddress) public {\n // trusted call\n
               require(masterInstance.checkTokenAddress(tokenAddress));\n if (tokenAddress == address(0)) {\n // trusted transfer\n
               masterAddress.transfer(address(this).balance);\n } else {\n IERC20 ic = IERC20(tokenAddress);\n // untrusted call
              in general but coin addresses are received from trusted master contract\n // which contains and manages whitelist of them\n
              ic.transfer(masterAddress, ic.balanceOf(address(this)));\n }\n }\n\n /**\n * Withdraws specified amount of ether or one of ERC-20
              tokens to provided address\n * @param tokenAddress address of token to withdraw (0 for ether)\n * @param amount amount of tokens or ether
              to withdraw\n * @param to target account address\n * @param tx_hash hash of transaction from Iroha\n * @param v array of signatures of
              tx_hash (v-component)\n * @param r array of signatures of tx_hash (r-component)\n * @param s array of signatures of tx_hash (s-component)\n
               * @param from relay contract address\n */\n function withdraw(\n address tokenAddress,\n uint256 amount,\n address
              payable to,\n bytes32 tx_hash,\n uint8[] memory v,\n bytes32[] memory r,\n bytes32[] memory s,\n address from\n
               )\n public\n {\n emit AddressEvent(masterAddress);\n // trusted call\n masterInstance.withdraw(tokenAddress, amount,
              to, tx_hash, v, r, s, from);\n }\n\n /**\n * Mint specified amount of ether or one of ERC-20 tokens to provided address\n * @param
              tokenAddress address to mint\n * @param amount how much to mint\n * @param beneficiary destination address\n * @param txHash hash of
              transaction from Iroha\n * @param v array of signatures of tx_hash (v-component)\n * @param r array of signatures of tx_hash (r-component
              )\n * @param s array of signatures of tx_hash (s-component)\n * @param from relay contract address\n */\n function mintTokensByPeers
              (\n address tokenAddress,\n uint256 amount,\n address beneficiary,\n bytes32 txHash,\n uint8[] memory v,\n
               bytes32[] memory r,\n bytes32[] memory s,\n address from\n )\n public\n {\n emit AddressEvent(masterAddress);\n
               // trusted call\n masterInstance.mintTokensByPeers(tokenAddress, amount, beneficiary, txHash, v, r, s, from);\n }\n}\n"}
              ,"RelayRegistry.sol":{"content":"pragma solidity ^0.5.8;\n\nimport \"./IRelayRegistry.sol\";\n\n/**\n * @title Relay registry store data about
              white list and provide interface for master\n */\ncontract RelayRegistry is IRelayRegistry {\n bool internal initialized_;\n address private
              owner_;\n\n mapping(address =\u003e address[]) private _relayWhiteList;\n\n constructor () public {\n initialize(msg.sender);\n
              }\n\n /**\n * Initialization of smart contract.\n */\n function initialize(address owner) public {\n require(!initialized_);\n
               owner_ = owner;\n initialized_ = true;\n }\n\n /**\n * Store relay address and appropriate whitelist of addresses\n *
              @param relay contract address\n * @param whiteList white list\n */\n function addNewRelayAddress(address relay, address[] calldata
              whiteList) external {\n require(msg.sender == owner_);\n require(_relayWhiteList[relay].length == 0);\n _relayWhiteList[relay]
              = whiteList;\n emit AddNewRelay(relay, whiteList);\n }\n\n /**\n * Check if some address is in the whitelist\n * @param relay
              contract address\n * @param who address in whitelist\n * @return true if address in the whitelist\n */\n function isWhiteListed
              (address relay, address who) external view returns (bool) {\n if (_relayWhiteList[relay].length == 0) {\n return true;\n
              }\n if (_relayWhiteList[relay].length \u003e 0) {\n for (uint i = 0; i \u003c _relayWhiteList[relay].length; i++) {\n
               if (who == _relayWhiteList[relay][i]) {\n return true;\n }\n }\n }\n return false;\n
               }\n\n /**\n * Get entire whitelist by relay address\n * @param relay contract address\n * @return array of the whitelist\n
              */\n function getWhiteListByRelay(address relay) external view returns (address[] memory ) {\n require(relay != address(0));\n
              require(_relayWhiteList[relay].length != 0);\n return _relayWhiteList[relay];\n }\n}\n"},"SafeMath.sol":{"content":"pragma solidity ^0.5
              .8;\n\n/**\n * @title SafeMath\n * @dev Unsigned math operations with safety checks that revert on error\n */\nlibrary SafeMath {\n /**\n *
              @dev Multiplies two unsigned integers, reverts on overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n
               // Gas optimization: this is cheaper than requiring \u0027a\u0027 not being zero, but the\n // benefit is lost if \u0027b\u0027 is also
              tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522\n if (a == 0) {\n return 0;\n
              }\n\n uint256 c = a * b;\n require(c / a == b);\n\n return c;\n }\n\n /**\n * @dev Integer division of two unsigned
              integers truncating the quotient, reverts on division by zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n
               // Solidity only automatically asserts when dividing by 0\n require(b \u003e 0);\n uint256 c = a / b;\n // assert(a ==
              b * c + a % b); // There is no case in which this doesn\u0027t hold\n\n return c;\n }\n\n /**\n * @dev Subtracts two unsigned
              integers, reverts on overflow (i.e. if subtrahend is greater than minuend).\n */\n function sub(uint256 a, uint256 b) internal pure returns
              (uint256) {\n require(b \u003c= a);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Adds two unsigned
              integers, reverts on overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n
               require(c \u003e= a);\n\n return c;\n }\n\n /**\n * @dev Divides two unsigned integers and returns the remainder (unsigned
              integer modulo),\n * reverts when dividing by zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n
              require(b != 0);\n return a % b;\n }\n}\n"},"SoraToken.sol":{"content":"pragma solidity ^0.5.8;\n\nimport \"./ERC20Detailed.sol\"
              ;\nimport \"./ERC20Burnable.sol\";\nimport \"./Ownable.sol\";\n\ncontract SoraToken is ERC20Burnable, ERC20Detailed, Ownable {\n\n uint256
              public constant INITIAL_SUPPLY = 0;\n\n /**\n * @dev Constructor that gives msg.sender all of existing tokens.\n */\n constructor()
              public ERC20Detailed(\"Sora Token\", \"XOR\", 18) {\n _mint(msg.sender, INITIAL_SUPPLY);\n }\n\n function mintTokens(address
              beneficiary, uint256 amount) public onlyOwner {\n _mint(beneficiary, amount);\n }\n\n}\n"},"TestGreeter_v0.sol":{"content":"pragma
              solidity ^0.5.8;\n\ncontract TestGreeter_v0 {\n bool ininialized_;\n\n string greeting_;\n\n constructor(string memory greeting) public
              {\n initialize(greeting);\n }\n\n function initialize(string memory greeting) public {\n require(!ininialized_);\n
              greeting_ = greeting;\n ininialized_ = true;\n }\n\n function greet() view public returns (string memory) {\n return greeting_
              ;\n }\n\n function set(string memory greeting) public {\n greeting_ = greeting;\n }\n}\n"},"TestGreeter_v1.sol":{"content":"pragma
              solidity ^0.5.8;\n\nimport \u0027./TestGreeter_v0.sol\u0027;\n\ncontract TestGreeter_v1 is TestGreeter_v0(\"Hi, World!\") {\n\n function
              farewell() public view returns (string memory) {\n return \"Good bye!\";\n }\n}\n"},"TransferEthereum.sol":{"content":"pragma solidity ^0
              .5.8;\n\n/**\n * Contract that sends Ether with internal transaction for testing purposes.\n */\ncontract TransferEthereum {\n\n\n /**\n * A
              special function-like stub to allow ether accepting\n */\n function() external payable {\n require(msg.data.length == 0);\n }\n\n
               function transfer(address payable to, uint256 amount) public {\n to.call.value(amount)(\"\");\n }\n\n}\n"},"UpgradeabilityProxy.sol"
              :{"content":"pragma solidity ^0.5.8;\n\nimport \u0027./Proxy.sol\u0027;\n\n/**\n * @title UpgradeabilityProxy\n * @dev This contract represents a
              proxy where the implementation address to which it will delegate can be upgraded\n */\ncontract UpgradeabilityProxy is Proxy {\n /**\n * @dev
              This event will be emitted every time the implementation gets upgraded\n * @param implementation representing the address of the upgraded
              implementation\n */\n event Upgraded(address indexed implementation);\n\n // Storage position of the address of the current implementation\n
              bytes32 private constant implementationPosition = keccak256(\"com.d3ledger.proxy.implementation\");\n\n /**\n * @dev Constructor function\n
              */\n constructor() public {}\n\n /**\n * @dev Tells the address of the current implementation\n * @return address of the current
              implementation\n */\n function implementation() public view returns (address impl) {\n bytes32 position = implementationPosition;\n
              assembly {\n impl := sload(position)\n }\n }\n\n /**\n * @dev Sets the address of the current implementation\n * @param
              newImplementation address representing the new implementation to be set\n */\n function setImplementation(address newImplementation) internal
              {\n bytes32 position = implementationPosition;\n assembly {\n sstore(position, newImplementation)\n }\n }\n\n /**\n * @dev
              Upgrades the implementation address\n * @param newImplementation representing the address of the new implementation to be set\n */\n function
              _upgradeTo(address newImplementation) internal {\n address currentImplementation = implementation();\n require(currentImplementation !=
              newImplementation);\n setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n}\n"}}
          XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

          File 4 of 4: FeeCollector
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          // SPDX-License-Identifier: GPL-2.0-or-later
          pragma solidity ^0.8.0;
          import {Owned} from "solmate/auth/Owned.sol";
          import {ERC20} from "solmate/tokens/ERC20.sol";
          import {SafeTransferLib} from "solmate/utils/SafeTransferLib.sol";
          import {IFeeCollector} from "./interfaces/IFeeCollector.sol";
          import {IPermit2} from "./external/IPermit2.sol";
          /// @notice The collector of protocol fees that will be used to swap and send to a fee recipient address.
          contract FeeCollector is Owned, IFeeCollector {
          using SafeTransferLib for ERC20;
          address public universalRouter;
          ERC20 public immutable feeToken;
          IPermit2 public immutable permit2;
          uint256 public constant MAX_APPROVAL_AMOUNT = type(uint256).max;
          uint160 public constant MAX_PERMIT2_APPROVAL_AMOUNT = type(uint160).max;
          uint48 public constant MAX_PERMIT2_DEADLINE = type(uint48).max;
          XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX