Transaction Hash:
Block:
12388598 at May-07-2021 05:53:49 PM +UTC
Transaction Fee:
0.00271081374 ETH
$5.50
Gas Used:
26,058 Gas / 104.03 Gwei
Emitted Events:
| 273 |
Bridge.Deposit( destination=5A4C043F5460F2BF88C46DC25D5D651C0DB2DD4D3D8B68F6D95B3235BC7CB44A, amount=300000000000000000, token=0x00000000...000000000, sidechainAsset=0000000000000000000000000000000000000000000000000000000000000000 )
|
Account State Difference:
| Address | Before | After | State Difference | ||
|---|---|---|---|---|---|
| 0x1485E985...504f4F602 | 2,641.231562116090959224 Eth | 2,641.531562116090959224 Eth | 0.3 | ||
|
0xEA674fdD...16B898ec8
Miner
| (Ethermine) | 1,345.939391779109823836 Eth | 1,345.942102592849823836 Eth | 0.00271081374 | |
| 0xF3Bdb13A...Fc5Cc6658 |
0.588696852472528655 Eth
Nonce: 35
|
0.285986038732528655 Eth
Nonce: 36
| 0.30271081374 |
Execution Trace
ETH 0.3
Bridge.sendEthToSidechain( to=5A4C043F5460F2BF88C46DC25D5D651C0DB2DD4D3D8B68F6D95B3235BC7CB44A )
{"Bridge.sol":{"content":"pragma solidity ^0.7.4;\n// \"SPDX-License-Identifier: Apache License 2.0\"\n\nimport \"./MasterToken.sol\";\nimport \"./Ownable.sol\";\nimport \"./ERC20Burnable.sol\";\n\n/**\n * Provides functionality of the HASHI bridge\n */\ncontract Bridge {\n bool internal initialized_;\n bool internal preparedForMigration_;\n\n mapping(address =\u003e bool) public isPeer;\n uint public peersCount;\n\n /** Substrate proofs used */\n mapping(bytes32 =\u003e bool) public used;\n mapping(address =\u003e bool) public _uniqueAddresses;\n\n /** White list of ERC-20 ethereum native tokens */\n mapping(address =\u003e bool) public acceptedEthTokens;\n\n /** White lists of ERC-20 SORA native tokens\n * We use several representations of the white list for optimisation purposes.\n */\n mapping(bytes32 =\u003e address) public _sidechainTokens;\n mapping(address =\u003e bytes32) public _sidechainTokensByAddress;\n address[] public _sidechainTokenAddressArray;\n\n event Withdrawal(bytes32 txHash);\n event Deposit(bytes32 destination, uint amount, address token, bytes32 sidechainAsset);\n event ChangePeers(address peerId, bool removal);\n event PreparedForMigration();\n event Migrated(address to);\n\n /**\n * For XOR and VAL use old token contracts, created for SORA 1 bridge.\n * Also for XOR and VAL transfers from SORA 2 to Ethereum old bridges will be used.\n */\n address public _addressVAL;\n address public _addressXOR;\n /** EVM netowrk ID */\n bytes32 public _networkId;\n\n /**\n * Constructor.\n * @param initialPeers - list of initial bridge validators on substrate side.\n * @param addressVAL address of VAL token Contract\n * @param addressXOR address of XOR token Contract\n * @param networkId id of current EvM network used for bridge purpose.\n */\n constructor(\n address[] memory initialPeers,\n address addressVAL,\n address addressXOR,\n bytes32 networkId) {\n for (uint8 i = 0; i \u003c initialPeers.length; i++) {\n addPeer(initialPeers[i]);\n }\n _addressXOR = addressXOR;\n _addressVAL = addressVAL;\n _networkId = networkId;\n initialized_ = true;\n preparedForMigration_ = false;\n\n acceptedEthTokens[_addressXOR] = true;\n acceptedEthTokens[_addressVAL] = true;\n }\n\n modifier shouldBeInitialized {\n require(initialized_ == true, \"Contract should be initialized to use this function\");\n _;\n }\n\n modifier shouldNotBePreparedForMigration {\n require(preparedForMigration_ == false, \"Contract should not be prepared for migration to use this function\");\n _;\n }\n\n modifier shouldBePreparedForMigration {\n require(preparedForMigration_ == true, \"Contract should be prepared for migration to use this function\");\n _;\n }\n\n fallback() external {\n revert();\n }\n\n receive() external payable {\n revert();\n }\n \n /*\n Used only for migration\n */\n function receivePayment() external payable {}\n\n /**\n * Adds new token to whitelist.\n * Token should not been already added.\n *\n * @param newToken new token contract address\n * @param ticker token ticker (symbol)\n * @param name token title\n * @param decimals count of token decimal places\n * @param txHash transaction hash from sidechain\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 addEthNativeToken(\n address newToken,\n string memory ticker,\n string memory name,\n uint8 decimals,\n bytes32 txHash,\n uint8[] memory v,\n bytes32[] memory r,\n bytes32[] memory s\n )\n public shouldBeInitialized {\n require(used[txHash] == false);\n require(acceptedEthTokens[newToken] == false);\n require(checkSignatures(keccak256(abi.encodePacked(newToken, ticker, name, decimals, txHash, _networkId)),\n v,\n r,\n s), \"Peer signatures are invalid\"\n );\n acceptedEthTokens[newToken] = true;\n used[txHash] = true;\n }\n\n /**\n * Preparations for migration to new Bridge contract\n *\n * @param thisContractAddress address of this bridge contract\n * @param salt unique data used for signature\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 prepareForMigration(\n address thisContractAddress,\n bytes32 salt,\n uint8[] memory v,\n bytes32[] memory r,\n bytes32[] memory s\n )\n public\n shouldBeInitialized shouldNotBePreparedForMigration {\n require(preparedForMigration_ == false);\n require(address(this) == thisContractAddress);\n require(checkSignatures(keccak256(abi.encodePacked(thisContractAddress, salt, _networkId)),\n v,\n r,\n s), \"Peer signatures are invalid\"\n );\n preparedForMigration_ = true;\n emit PreparedForMigration();\n }\n\n /**\n * Shutdown this contract and migrate tokens ownership to the new contract.\n *\n * @param thisContractAddress this bridge contract address\n * @param salt unique data used for signature generation\n * @param newContractAddress address of the new bridge contract\n * @param erc20nativeTokens list of ERC20 tokens with non zero balances for this contract. Can be taken from substrate bridge peers.\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 shutDownAndMigrate(\n address thisContractAddress,\n bytes32 salt,\n address payable newContractAddress,\n address[] calldata erc20nativeTokens,\n uint8[] memory v,\n bytes32[] memory r,\n bytes32[] memory s\n )\n public\n shouldBeInitialized shouldBePreparedForMigration {\n require(address(this) == thisContractAddress);\n require(checkSignatures(keccak256(abi.encodePacked(thisContractAddress, newContractAddress, salt, erc20nativeTokens, _networkId)),\n v,\n r,\n s), \"Peer signatures are invalid\"\n );\n for (uint i = 0; i \u003c _sidechainTokenAddressArray.length; i++) {\n Ownable token = Ownable(_sidechainTokenAddressArray[i]);\n token.transferOwnership(newContractAddress);\n }\n for (uint i = 0; i \u003c erc20nativeTokens.length; i++) {\n IERC20 token = IERC20(erc20nativeTokens[i]);\n token.transfer(newContractAddress, token.balanceOf(address(this)));\n }\n Bridge(newContractAddress).receivePayment{value: address(this).balance}();\n initialized_ = false;\n emit Migrated(newContractAddress);\n }\n\n /**\n * Add new token from sidechain to the bridge white list.\n *\n * @param name token title\n * @param symbol token symbol\n * @param decimals number of decimals\n * @param sidechainAssetId token id on the sidechain\n * @param txHash sidechain transaction hash\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 addNewSidechainToken(\n string memory name,\n string memory symbol,\n uint8 decimals,\n bytes32 sidechainAssetId,\n bytes32 txHash,\n uint8[] memory v,\n bytes32[] memory r,\n bytes32[] memory s)\n public shouldBeInitialized {\n require(used[txHash] == false);\n require(checkSignatures(keccak256(abi.encodePacked(\n name,\n symbol,\n decimals,\n sidechainAssetId,\n txHash,\n _networkId\n )),\n v,\n r,\n s), \"Peer signatures are invalid\"\n );\n // Create new instance of the token\n MasterToken tokenInstance = new MasterToken(name, symbol, decimals, address(this), 0, sidechainAssetId);\n address tokenAddress = address(tokenInstance);\n _sidechainTokens[sidechainAssetId] = tokenAddress;\n _sidechainTokensByAddress[tokenAddress] = sidechainAssetId;\n _sidechainTokenAddressArray.push(tokenAddress);\n used[txHash] = true;\n }\n\n /**\n * Send Ethereum to sidechain.\n *\n * @param to destionation address on sidechain.\n */\n function sendEthToSidechain(\n bytes32 to\n )\n public\n payable\n shouldBeInitialized shouldNotBePreparedForMigration {\n require(msg.value \u003e 0, \"ETH VALUE SHOULD BE MORE THAN 0\");\n bytes32 empty;\n emit Deposit(to, msg.value, address(0x0), empty);\n }\n\n /**\n * Send ERC-20 token to sidechain.\n *\n * @param to destination address on the sidechain\n * @param amount amount to sendERC20ToSidechain\n * @param tokenAddress contract address of token to send\n */\n function sendERC20ToSidechain(\n bytes32 to,\n uint amount,\n address tokenAddress)\n external\n shouldBeInitialized shouldNotBePreparedForMigration {\n IERC20 token = IERC20(tokenAddress);\n\n require(token.allowance(msg.sender, address(this)) \u003e= amount, \"NOT ENOUGH DELEGATED TOKENS ON SENDER BALANCE\");\n\n bytes32 sidechainAssetId = _sidechainTokensByAddress[tokenAddress];\n if (sidechainAssetId != \"\" || _addressVAL == tokenAddress || _addressXOR == tokenAddress) {\n ERC20Burnable mtoken = ERC20Burnable(tokenAddress);\n mtoken.burnFrom(msg.sender, amount);\n } else {\n require(acceptedEthTokens[tokenAddress], \"The Token is not accepted for transfer to sidechain\");\n token.transferFrom(msg.sender, address(this), amount);\n }\n emit Deposit(to, amount, tokenAddress, sidechainAssetId);\n }\n\n /**\n * Add new peer using peers quorum.\n *\n * @param newPeerAddress address of the peer to add\n * @param txHash tx hash from sidechain\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 addPeerByPeer(\n address newPeerAddress,\n bytes32 txHash,\n uint8[] memory v,\n bytes32[] memory r,\n bytes32[] memory s\n )\n public\n shouldBeInitialized\n returns (bool)\n {\n require(used[txHash] == false);\n require(checkSignatures(keccak256(abi.encodePacked(newPeerAddress, txHash, _networkId)),\n v,\n r,\n s), \"Peer signatures are invalid\"\n );\n\n addPeer(newPeerAddress);\n used[txHash] = true;\n emit ChangePeers(newPeerAddress, false);\n return true;\n }\n\n /**\n * Remove peer using peers quorum.\n *\n * @param peerAddress address of the peer to remove\n * @param txHash tx hash from sidechain\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 removePeerByPeer(\n address peerAddress,\n bytes32 txHash,\n uint8[] memory v,\n bytes32[] memory r,\n bytes32[] memory s\n )\n public\n shouldBeInitialized\n returns (bool)\n {\n require(used[txHash] == false);\n require(checkSignatures(\n keccak256(abi.encodePacked(peerAddress, txHash, _networkId)),\n v,\n r,\n s), \"Peer signatures are invalid\"\n );\n\n removePeer(peerAddress);\n used[txHash] = true;\n emit ChangePeers(peerAddress, true);\n return true;\n }\n\n /**\n * Withdraws specified amount of ether or one of ERC-20 tokens to provided sidechain 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 sidechain\n * @param from source of transfer\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 receiveByEthereumAssetAddress(\n address tokenAddress,\n uint256 amount,\n address payable to,\n address from,\n bytes32 txHash,\n uint8[] memory v,\n bytes32[] memory r,\n bytes32[] memory s\n )\n public shouldBeInitialized\n {\n require(used[txHash] == false);\n require(checkSignatures(\n keccak256(abi.encodePacked(tokenAddress, amount, to, from, txHash, _networkId)),\n v,\n r,\n s), \"Peer signatures are invalid\"\n );\n\n if (tokenAddress == address(0)) {\n used[txHash] = true;\n // untrusted transfer, relies on provided cryptographic proof\n to.transfer(amount);\n } else {\n IERC20 coin = IERC20(tokenAddress);\n used[txHash] = true;\n // untrusted call, relies on provided cryptographic proof\n coin.transfer(to, amount);\n }\n emit Withdrawal(txHash);\n }\n\n /**\n * Mint new Token\n * @param sidechainAssetId id of sidechainToken to mint\n * @param amount how much to mint\n * @param to destination address\n * @param from sender 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 receiveBySidechainAssetId(\n bytes32 sidechainAssetId,\n uint256 amount,\n address to,\n address from,\n bytes32 txHash,\n uint8[] memory v,\n bytes32[] memory r,\n bytes32[] memory s\n )\n public shouldBeInitialized\n {\n require(_sidechainTokens[sidechainAssetId] != address(0x0), \"Sidechain asset is not registered\");\n require(used[txHash] == false);\n require(checkSignatures(\n keccak256(abi.encodePacked(sidechainAssetId, amount, to, from, txHash, _networkId)),\n v,\n r,\n s), \"Peer signatures are invalid\"\n );\n\n MasterToken tokenInstance = MasterToken(_sidechainTokens[sidechainAssetId]);\n tokenInstance.mintTokens(to, amount);\n used[txHash] = true;\n emit Withdrawal(txHash);\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 )\n private\n 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(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s)\n private\n pure\n 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 * Adds new peer to list of signature verifiers.\n * Internal function\n * @param newAddress address of new peer\n */\n function addPeer(address newAddress)\n internal\n returns (uint) {\n require(isPeer[newAddress] == false);\n isPeer[newAddress] = true;\n ++peersCount;\n return peersCount;\n }\n\n function removePeer(address peerAddress)\n internal {\n require(isPeer[peerAddress] == true);\n isPeer[peerAddress] = false;\n --peersCount;\n }\n}"},"ERC20.sol":{"content":"pragma solidity ^0.7.4;\n// \"SPDX-License-Identifier: Apache License 2.0\"\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 override 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 override 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 override 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 override 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 override 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 override 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}"},"ERC20Burnable.sol":{"content":"pragma solidity ^0.7.4;\n// \"SPDX-License-Identifier: Apache License 2.0\"\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}"},"ERC20Detailed.sol":{"content":"pragma solidity ^0.7.4;\n// \"SPDX-License-Identifier: Apache License 2.0\"\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 */\nabstract contract ERC20Detailed is IERC20 {\n string private _name;\n string private _symbol;\n uint8 private _decimals;\n\n constructor (\n string memory name_, \n string memory symbol_, \n uint8 decimals_) {\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}"},"IERC20.sol":{"content":"pragma solidity ^0.7.4;\n// \"SPDX-License-Identifier: MIT\"\n\ninterface IERC20 {\n function totalSupply() external view returns (uint256);\n function balanceOf(address account) external view returns (uint256);\n function allowance(address owner, address spender) external view returns (uint256);\n function transfer(address recipient, uint256 amount) external returns (bool);\n function approve(address spender, uint256 amount) external returns (bool);\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}"},"MasterToken.sol":{"content":"pragma solidity ^0.7.4;\n// \"SPDX-License-Identifier: Apache License 2.0\"\n\nimport \"./ERC20Detailed.sol\";\nimport \"./ERC20Burnable.sol\";\nimport \"./Ownable.sol\";\n\ncontract MasterToken is ERC20Burnable, ERC20Detailed, Ownable {\n\n bytes32 public _sidechainAssetId;\n\n /**\n * @dev Constructor that gives the specified address all of existing tokens.\n */\n constructor(\n string memory name, \n string memory symbol, \n uint8 decimals, \n address beneficiary, \n uint256 supply,\n bytes32 sidechainAssetId) \n ERC20Detailed(name, symbol, decimals) {\n _sidechainAssetId = sidechainAssetId; \n _mint(beneficiary, supply);\n \n }\n \n fallback() external {\n revert();\n }\n\n function mintTokens(address beneficiary, uint256 amount) public onlyOwner {\n _mint(beneficiary, amount);\n }\n\n}"},"Ownable.sol":{"content":"pragma solidity ^0.7.4;\n// \"SPDX-License-Identifier: Apache License 2.0\"\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 */\nabstract contract 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 () {\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}"},"SafeMath.sol":{"content":"pragma solidity ^0.7.4;\n// \"SPDX-License-Identifier: Apache License 2.0\"\n\n\n/**\n * @dev Wrappers over Solidity\u0027s arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it\u0027s recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity\u0027s `+` operator.\n *\n * Requirements:\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c \u003e= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity\u0027s `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity\u0027s `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b \u003c= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity\u0027s `*` operator.\n *\n * Requirements:\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring \u0027a\u0027 not being zero, but the\n // benefit is lost if \u0027b\u0027 is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity\u0027s `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity\u0027s `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n // Solidity only automatically asserts when dividing by 0\n require(b \u003e 0, errorMessage);\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 Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts when dividing by zero.\n *\n * Counterpart to Solidity\u0027s `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts with custom message when dividing by zero.\n *\n * Counterpart to Solidity\u0027s `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n}"}}