ERC-20
Overview
Max Total Supply
94,401,791,694.444495356087328577 XOR
Holders
17,625 ( 0.040%)
Market
Price
$0.00 @ 0.000000 ETH (+0.85%)
Onchain Market Cap
$701,405.31
Circulating Supply Market Cap
$2,658,498.00
Other Info
Token Contract (WITH 18 Decimals)
Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
SoraToken
Compiler Version
v0.5.9+commit.e560f70d
Contract Source Code (Solidity Multiple files format)
pragma solidity ^0.5.8; import "./ERC20Detailed.sol"; import "./ERC20Burnable.sol"; import "./Ownable.sol"; contract SoraToken is ERC20Burnable, ERC20Detailed, Ownable { uint256 public constant INITIAL_SUPPLY = 0; /** * @dev Constructor that gives msg.sender all of existing tokens. */ constructor() public ERC20Detailed("Sora Token", "XOR", 18) { _mint(msg.sender, INITIAL_SUPPLY); } function mintTokens(address beneficiary, uint256 amount) public onlyOwner { _mint(beneficiary, amount); } }
//! The basic-coin ECR20-compliant token contract. //! //! Copyright 2016 Gavin Wood, Parity Technologies Ltd. //! //! Licensed under the Apache License, Version 2.0 (the "License"); //! you may not use this file except in compliance with the License. //! You may obtain a copy of the License at //! //! http://www.apache.org/licenses/LICENSE-2.0 //! //! Unless required by applicable law or agreed to in writing, software //! distributed under the License is distributed on an "AS IS" BASIS, //! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //! See the License for the specific language governing permissions and //! limitations under the License. pragma solidity ^0.5.8; contract Owned { modifier only_owner { require(msg.sender == owner); _; } event NewOwner(address indexed old, address indexed current); function setOwner(address _new) only_owner public { emit NewOwner(owner, _new); owner = _new; } address public owner = msg.sender; } interface Token { event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); function balanceOf(address _owner) view external returns (uint256 balance); function transfer(address _to, uint256 _value) external returns (bool success); function transferFrom(address _from, address _to, uint256 _value) external returns (bool success); function approve(address _spender, uint256 _value) external returns (bool success); function allowance(address _owner, address _spender) view external returns (uint256 remaining); } // TokenReg interface contract TokenReg { function register(address _addr, string memory _tla, uint _base, string memory _name) public payable returns (bool); function registerAs(address _addr, string memory _tla, uint _base, string memory _name, address _owner) public payable returns (bool); function unregister(uint _id) public; function setFee(uint _fee) public; function tokenCount() public view returns (uint); function token(uint _id) public view returns (address addr, string memory tla, uint base, string memory name, address owner); function fromAddress(address _addr) public view returns (uint id, string memory tla, uint base, string memory name, address owner); function fromTLA(string memory _tla) public view returns (uint id, address addr, uint base, string memory name, address owner); function meta(uint _id, bytes32 _key) public view returns (bytes32); function setMeta(uint _id, bytes32 _key, bytes32 _value) public; function drain() public; uint public fee; } // BasicCoin, ECR20 tokens that all belong to the owner for sending around contract BasicCoin is Owned, Token { // this is as basic as can be, only the associated balance & allowances struct Account { uint balance; mapping (address => uint) allowanceOf; } // the balance should be available modifier when_owns(address _owner, uint _amount) { if (accounts[_owner].balance < _amount) revert(); _; } // an allowance should be available modifier when_has_allowance(address _owner, address _spender, uint _amount) { if (accounts[_owner].allowanceOf[_spender] < _amount) revert(); _; } // a value should be > 0 modifier when_non_zero(uint _value) { if (_value == 0) revert(); _; } bool public called = false; // the base, tokens denoted in micros uint constant public base = 1000000; // available token supply uint public totalSupply; // storage and mapping of all balances & allowances mapping (address => Account) accounts; // constructor sets the parameters of execution, _totalSupply is all units constructor(uint _totalSupply, address _owner) public when_non_zero(_totalSupply) { totalSupply = _totalSupply; owner = _owner; accounts[_owner].balance = totalSupply; } // balance of a specific address function balanceOf(address _who) public view returns (uint256) { return accounts[_who].balance; } // transfer function transfer(address _to, uint256 _value) public when_owns(msg.sender, _value) returns (bool) { emit Transfer(msg.sender, _to, _value); accounts[msg.sender].balance -= _value; accounts[_to].balance += _value; return true; } // transfer via allowance function transferFrom(address _from, address _to, uint256 _value) public when_owns(_from, _value) when_has_allowance(_from, msg.sender, _value) returns (bool) { called = true; emit Transfer(_from, _to, _value); accounts[_from].allowanceOf[msg.sender] -= _value; accounts[_from].balance -= _value; accounts[_to].balance += _value; return true; } // approve allowances function approve(address _spender, uint256 _value) public returns (bool) { emit Approval(msg.sender, _spender, _value); accounts[msg.sender].allowanceOf[_spender] += _value; return true; } // available allowance function allowance(address _owner, address _spender) public view returns (uint256) { return accounts[_owner].allowanceOf[_spender]; } // no default function, simple contract only, entry-level users function() external { revert(); } } // Manages BasicCoin instances, including the deployment & registration contract BasicCoinManager is Owned { // a structure wrapping a deployed BasicCoin struct Coin { address coin; address owner; address tokenreg; } // a new BasicCoin has been deployed event Created(address indexed owner, address indexed tokenreg, address indexed coin); // a list of all the deployed BasicCoins Coin[] coins; // all BasicCoins for a specific owner mapping (address => uint[]) ownedCoins; // the base, tokens denoted in micros (matches up with BasicCoin interface above) uint constant public base = 1000000; // return the number of deployed function count() public view returns (uint) { return coins.length; } // get a specific deployment function get(uint _index) public view returns (address coin, address owner, address tokenreg) { Coin memory c = coins[_index]; coin = c.coin; owner = c.owner; tokenreg = c.tokenreg; } // returns the number of coins for a specific owner function countByOwner(address _owner) public view returns (uint) { return ownedCoins[_owner].length; } // returns a specific index by owner function getByOwner(address _owner, uint _index) public view returns (address coin, address owner, address tokenreg) { return get(ownedCoins[_owner][_index]); } // deploy a new BasicCoin on the blockchain function deploy(uint _totalSupply, string memory _tla, string memory _name, address _tokenreg) public payable returns (bool) { TokenReg tokenreg = TokenReg(_tokenreg); BasicCoin coin = new BasicCoin(_totalSupply, msg.sender); uint ownerCount = countByOwner(msg.sender); uint fee = tokenreg.fee(); ownedCoins[msg.sender].length = ownerCount + 1; ownedCoins[msg.sender][ownerCount] = coins.length; coins.push(Coin(address(coin), msg.sender, address(tokenreg))); tokenreg.registerAs.value(fee)(address(coin), _tla, base, _name, msg.sender); emit Created(msg.sender, address(tokenreg), address(coin)); return true; } // owner can withdraw all collected funds function drain() public only_owner { if (!msg.sender.send(address(this).balance)) { revert(); } } }
pragma solidity ^0.5.8; import "./IERC20.sol"; import "./SafeMath.sol"; /** * @title Standard ERC20 token * * @dev Implementation of the basic standard token. * https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md * Originally based on code by FirstBlood: * https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol * * This implementation emits additional Approval events, allowing applications to reconstruct the allowance status for * all accounts just by listening to said events. Note that this isn't required by the specification, and other * compliant implementations may not do it. */ contract ERC20 is IERC20 { using SafeMath for uint256; mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowed; uint256 private _totalSupply; /** * @dev Total number of tokens in existence */ function totalSupply() public view returns (uint256) { return _totalSupply; } /** * @dev Gets the balance of the specified address. * @param owner The address to query the balance of. * @return An uint256 representing the amount owned by the passed address. */ function balanceOf(address owner) public view returns (uint256) { return _balances[owner]; } /** * @dev Function to check the amount of tokens that an owner allowed to a spender. * @param owner address The address which owns the funds. * @param spender address The address which will spend the funds. * @return A uint256 specifying the amount of tokens still available for the spender. */ function allowance(address owner, address spender) public view returns (uint256) { return _allowed[owner][spender]; } /** * @dev Transfer token for a specified address * @param to The address to transfer to. * @param value The amount to be transferred. */ function transfer(address to, uint256 value) public returns (bool) { _transfer(msg.sender, to, value); return true; } /** * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender. * Beware that changing an allowance with this method brings the risk that someone may use both the old * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. */ function approve(address spender, uint256 value) public returns (bool) { _approve(msg.sender, spender, value); return true; } /** * @dev Transfer tokens from one address to another. * Note that while this function emits an Approval event, this is not required as per the specification, * and other compliant implementations may not emit the event. * @param from address The address which you want to send tokens from * @param to address The address which you want to transfer to * @param value uint256 the amount of tokens to be transferred */ function transferFrom(address from, address to, uint256 value) public returns (bool) { _transfer(from, to, value); _approve(from, msg.sender, _allowed[from][msg.sender].sub(value)); return true; } /** * @dev Increase the amount of tokens that an owner allowed to a spender. * approve should be called when allowed_[_spender] == 0. To increment * allowed value is better to use this function to avoid 2 calls (and wait until * the first transaction is mined) * From MonolithDAO Token.sol * Emits an Approval event. * @param spender The address which will spend the funds. * @param addedValue The amount of tokens to increase the allowance by. */ function increaseAllowance(address spender, uint256 addedValue) public returns (bool) { _approve(msg.sender, spender, _allowed[msg.sender][spender].add(addedValue)); return true; } /** * @dev Decrease the amount of tokens that an owner allowed to a spender. * approve should be called when allowed_[_spender] == 0. To decrement * allowed value is better to use this function to avoid 2 calls (and wait until * the first transaction is mined) * From MonolithDAO Token.sol * Emits an Approval event. * @param spender The address which will spend the funds. * @param subtractedValue The amount of tokens to decrease the allowance by. */ function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) { _approve(msg.sender, spender, _allowed[msg.sender][spender].sub(subtractedValue)); return true; } /** * @dev Transfer token for a specified addresses * @param from The address to transfer from. * @param to The address to transfer to. * @param value The amount to be transferred. */ function _transfer(address from, address to, uint256 value) internal { require(to != address(0)); _balances[from] = _balances[from].sub(value); _balances[to] = _balances[to].add(value); emit Transfer(from, to, value); } /** * @dev Internal function that mints an amount of the token and assigns it to * an account. This encapsulates the modification of balances such that the * proper events are emitted. * @param account The account that will receive the created tokens. * @param value The amount that will be created. */ function _mint(address account, uint256 value) internal { require(account != address(0)); _totalSupply = _totalSupply.add(value); _balances[account] = _balances[account].add(value); emit Transfer(address(0), account, value); } /** * @dev Internal function that burns an amount of the token of a given * account. * @param account The account whose tokens will be burnt. * @param value The amount that will be burnt. */ function _burn(address account, uint256 value) internal { require(account != address(0)); _totalSupply = _totalSupply.sub(value); _balances[account] = _balances[account].sub(value); emit Transfer(account, address(0), value); } /** * @dev Approve an address to spend another addresses' tokens. * @param owner The address that owns the tokens. * @param spender The address that will spend the tokens. * @param value The number of tokens that can be spent. */ function _approve(address owner, address spender, uint256 value) internal { require(spender != address(0)); require(owner != address(0)); _allowed[owner][spender] = value; emit Approval(owner, spender, value); } /** * @dev Internal function that burns an amount of the token of a given * account, deducting from the sender's allowance for said account. Uses the * internal burn function. * Emits an Approval event (reflecting the reduced allowance). * @param account The account whose tokens will be burnt. * @param value The amount that will be burnt. */ function _burnFrom(address account, uint256 value) internal { _burn(account, value); _approve(account, msg.sender, _allowed[account][msg.sender].sub(value)); } }
pragma solidity ^0.5.8; import "./ERC20.sol"; /** * @title Burnable Token * @dev Token that can be irreversibly burned (destroyed). */ contract ERC20Burnable is ERC20 { /** * @dev Burns a specific amount of tokens. * @param value The amount of token to be burned. */ function burn(uint256 value) public { _burn(msg.sender, value); } /** * @dev Burns a specific amount of tokens from the target address and decrements allowance * @param from address The address which you want to send tokens from * @param value uint256 The amount of token to be burned */ function burnFrom(address from, uint256 value) public { _burnFrom(from, value); } }
pragma solidity ^0.5.8; import "./IERC20.sol"; /** * @title ERC20Detailed token * @dev The decimals are only for visualization purposes. * All the operations are done using the smallest and indivisible token unit, * just as on Ethereum all the operations are done in wei. */ contract ERC20Detailed is IERC20 { string private _name; string private _symbol; uint8 private _decimals; constructor (string memory name, string memory symbol, uint8 decimals) public { _name = name; _symbol = symbol; _decimals = decimals; } /** * @return the name of the token. */ function name() public view returns (string memory) { return _name; } /** * @return the symbol of the token. */ function symbol() public view returns (string memory) { return _symbol; } /** * @return the number of decimals of the token. */ function decimals() public view returns (uint8) { return _decimals; } }
pragma solidity ^0.5.8; /** * Contract for revert cases testing */ contract Failer { /** * A special function-like stub to allow ether accepting. Always fails. */ function() external payable { revert("eth transfer revert"); } /** * Fake ERC-20 transfer function. Always fails. */ function transfer(address, uint256) external pure { revert("ERC-20 transfer revert"); } }
pragma solidity ^0.5.8; /** * @title ERC20 interface * @dev see https://github.com/ethereum/EIPs/issues/20 */ interface IERC20 { function transfer(address to, uint256 value) external returns (bool); function approve(address spender, uint256 value) external returns (bool); function transferFrom(address from, address to, uint256 value) external returns (bool); function totalSupply() external view returns (uint256); function balanceOf(address who) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); }
pragma solidity ^0.5.8; /** * Subset of master contract interface */ contract IMaster { function withdraw( address tokenAddress, uint256 amount, address to, bytes32 txHash, uint8[] memory v, bytes32[] memory r, bytes32[] memory s, address from ) public; function mintTokensByPeers( address tokenAddress, uint256 amount, address beneficiary, bytes32 txHash, uint8[] memory v, bytes32[] memory r, bytes32[] memory s, address from ) public; function checkTokenAddress(address token) public view returns (bool); }
pragma solidity ^0.5.8; /** * @title Relay registry interface */ interface IRelayRegistry { /** * Store relay address and appropriate whitelist of addresses * @param relay contract address * @param whiteList with allowed addresses * @return true if data was stored */ function addNewRelayAddress(address relay, address[] calldata whiteList) external; /** * Check if some address is in the whitelist * @param relay contract address * @param who address in whitelist * @return true if address in the whitelist */ function isWhiteListed(address relay, address who) external view returns (bool); /** * Get entire whitelist by relay address * @param relay contract address * @return array of the whitelist */ function getWhiteListByRelay(address relay) external view returns (address[] memory); event AddNewRelay ( address indexed relayAddress, address[] indexed whiteList ); }
pragma solidity ^0.5.8; import "./IERC20.sol"; import "./SoraToken.sol"; /** * Provides functionality of master contract */ contract Master { bool internal initialized_; address public owner_; mapping(address => bool) public isPeer; uint public peersCount; /** Iroha tx hashes used */ mapping(bytes32 => bool) public used; mapping(address => bool) public uniqueAddresses; /** registered client addresses */ mapping(address => bytes) public registeredClients; SoraToken public xorTokenInstance; mapping(address => bool) public isToken; /** * Emit event on new registration with iroha acountId */ event IrohaAccountRegistration(address ethereumAddress, bytes accountId); /** * Emit event when master contract does not have enough assets to proceed withdraw */ event InsufficientFundsForWithdrawal(address asset, address recipient); /** * Constructor. Sets contract owner to contract creator. */ constructor(address[] memory initialPeers) public { initialize(msg.sender, initialPeers); } /** * Initialization of smart contract. */ function initialize(address owner, address[] memory initialPeers) public { require(!initialized_); owner_ = owner; for (uint8 i = 0; i < initialPeers.length; i++) { addPeer(initialPeers[i]); } // 0 means ether which is definitely in whitelist isToken[address(0)] = true; // Create new instance of Sora token xorTokenInstance = new SoraToken(); isToken[address(xorTokenInstance)] = true; initialized_ = true; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(isOwner()); _; } /** * @return true if `msg.sender` is the owner of the contract. */ function isOwner() public view returns(bool) { return msg.sender == owner_; } /** * A special function-like stub to allow ether accepting */ function() external payable { require(msg.data.length == 0); } /** * Adds new peer to list of signature verifiers. Can be called only by contract owner. * @param newAddress address of new peer */ function addPeer(address newAddress) private returns (uint) { require(isPeer[newAddress] == false); isPeer[newAddress] = true; ++peersCount; return peersCount; } function removePeer(address peerAddress) private { require(isPeer[peerAddress] == true); isPeer[peerAddress] = false; --peersCount; } function addPeerByPeer( address newPeerAddress, bytes32 txHash, uint8[] memory v, bytes32[] memory r, bytes32[] memory s ) public returns (bool) { require(used[txHash] == false); require(checkSignatures(keccak256(abi.encodePacked(newPeerAddress, txHash)), v, r, s) ); addPeer(newPeerAddress); used[txHash] = true; return true; } function removePeerByPeer( address peerAddress, bytes32 txHash, uint8[] memory v, bytes32[] memory r, bytes32[] memory s ) public returns (bool) { require(used[txHash] == false); require(checkSignatures( keccak256(abi.encodePacked(peerAddress, txHash)), v, r, s) ); removePeer(peerAddress); used[txHash] = true; return true; } /** * Adds new token to whitelist. Token should not been already added. * @param newToken token to add */ function addToken(address newToken) public onlyOwner { require(isToken[newToken] == false); isToken[newToken] = true; } /** * Checks is given token inside a whitelist or not * @param tokenAddress address of token to check * @return true if token inside whitelist or false otherwise */ function checkTokenAddress(address tokenAddress) public view returns (bool) { return isToken[tokenAddress]; } /** * Register a clientIrohaAccountId for the caller clientEthereumAddress * @param clientEthereumAddress - ethereum address to register * @param clientIrohaAccountId - iroha account id * @param txHash - iroha tx hash of registration * @param v array of signatures of tx_hash (v-component) * @param r array of signatures of tx_hash (r-component) * @param s array of signatures of tx_hash (s-component) */ function register( address clientEthereumAddress, bytes memory clientIrohaAccountId, bytes32 txHash, uint8[] memory v, bytes32[] memory r, bytes32[] memory s ) public { require(used[txHash] == false); require(checkSignatures( keccak256(abi.encodePacked(clientEthereumAddress, clientIrohaAccountId, txHash)), v, r, s) ); require(clientEthereumAddress == msg.sender); require(registeredClients[clientEthereumAddress].length == 0); registeredClients[clientEthereumAddress] = clientIrohaAccountId; emit IrohaAccountRegistration(clientEthereumAddress, clientIrohaAccountId); } /** * Withdraws specified amount of ether or one of ERC-20 tokens to provided address * @param tokenAddress address of token to withdraw (0 for ether) * @param amount amount of tokens or ether to withdraw * @param to target account address * @param txHash hash of transaction from Iroha * @param v array of signatures of tx_hash (v-component) * @param r array of signatures of tx_hash (r-component) * @param s array of signatures of tx_hash (s-component) * @param from relay contract address */ function withdraw( address tokenAddress, uint256 amount, address payable to, bytes32 txHash, uint8[] memory v, bytes32[] memory r, bytes32[] memory s, address from ) public { require(checkTokenAddress(tokenAddress)); require(used[txHash] == false); require(checkSignatures( keccak256(abi.encodePacked(tokenAddress, amount, to, txHash, from)), v, r, s) ); if (tokenAddress == address (0)) { if (address(this).balance < amount) { emit InsufficientFundsForWithdrawal(tokenAddress, to); } else { used[txHash] = true; // untrusted transfer, relies on provided cryptographic proof to.transfer(amount); } } else { IERC20 coin = IERC20(tokenAddress); if (coin.balanceOf(address (this)) < amount) { emit InsufficientFundsForWithdrawal(tokenAddress, to); } else { used[txHash] = true; // untrusted call, relies on provided cryptographic proof coin.transfer(to, amount); } } } /** * Checks given addresses for duplicates and if they are peers signatures * @param hash unsigned data * @param v v-component of signature from hash * @param r r-component of signature from hash * @param s s-component of signature from hash * @return true if all given addresses are correct or false otherwise */ function checkSignatures(bytes32 hash, uint8[] memory v, bytes32[] memory r, bytes32[] memory s ) private returns (bool) { require(peersCount >= 1); require(v.length == r.length); require(r.length == s.length); uint needSigs = peersCount - (peersCount - 1) / 3; require(s.length >= needSigs); uint count = 0; address[] memory recoveredAddresses = new address[](s.length); for (uint i = 0; i < s.length; ++i) { address recoveredAddress = recoverAddress( hash, v[i], r[i], s[i] ); // not a peer address or not unique if (isPeer[recoveredAddress] != true || uniqueAddresses[recoveredAddress] == true) { continue; } recoveredAddresses[count] = recoveredAddress; count = count + 1; uniqueAddresses[recoveredAddress] = true; } // restore state for future usages for (uint i = 0; i < count; ++i) { uniqueAddresses[recoveredAddresses[i]] = false; } return count >= needSigs; } /** * Recovers address from a given single signature * @param hash unsigned data * @param v v-component of signature from hash * @param r r-component of signature from hash * @param s s-component of signature from hash * @return address recovered from signature */ function recoverAddress(bytes32 hash, uint8 v, bytes32 r, bytes32 s) private pure returns (address) { bytes32 simple_hash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); address res = ecrecover(simple_hash, v, r, s); return res; } /** * Mint new XORToken * @param tokenAddress address to mint * @param amount how much to mint * @param beneficiary destination address * @param txHash hash of transaction from Iroha * @param v array of signatures of tx_hash (v-component) * @param r array of signatures of tx_hash (r-component) * @param s array of signatures of tx_hash (s-component) */ function mintTokensByPeers( address tokenAddress, uint256 amount, address beneficiary, bytes32 txHash, uint8[] memory v, bytes32[] memory r, bytes32[] memory s, address from ) public { require(address(xorTokenInstance) == tokenAddress); require(used[txHash] == false); require(checkSignatures( keccak256(abi.encodePacked(tokenAddress, amount, beneficiary, txHash, from)), v, r, s) ); xorTokenInstance.mintTokens(beneficiary, amount); used[txHash] = true; } }
pragma solidity ^0.5.8; import "./IRelayRegistry.sol"; import "./IERC20.sol"; import "./SoraToken.sol"; /** * Provides functionality of master contract with relays */ contract MasterRelayed { bool internal initialized_; address public owner_; mapping(address => bool) public isPeer; /** Iroha tx hashes used */ uint public peersCount; mapping(bytes32 => bool) public used; mapping(address => bool) public uniqueAddresses; /** registered client addresses */ address public relayRegistryAddress; IRelayRegistry public relayRegistryInstance; SoraToken public xorTokenInstance; mapping(address => bool) public isToken; /** * Emit event when master contract does not have enough assets to proceed withdraw */ event InsufficientFundsForWithdrawal(address asset, address recipient); /** * Constructor. Sets contract owner to contract creator. */ constructor(address relayRegistry, address[] memory initialPeers) public { initialize(msg.sender, relayRegistry, initialPeers); } /** * Initialization of smart contract. */ function initialize(address owner, address relayRegistry, address[] memory initialPeers) public { require(!initialized_); owner_ = owner; relayRegistryAddress = relayRegistry; relayRegistryInstance = IRelayRegistry(relayRegistryAddress); for (uint8 i = 0; i < initialPeers.length; i++) { addPeer(initialPeers[i]); } // 0 means ether which is definitely in whitelist isToken[address(0)] = true; // Create new instance of Sora token xorTokenInstance = new SoraToken(); isToken[address(xorTokenInstance)] = true; initialized_ = true; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(isOwner()); _; } /** * @return true if `msg.sender` is the owner of the contract. */ function isOwner() public view returns(bool) { return msg.sender == owner_; } /** * A special function-like stub to allow ether accepting */ function() external payable { require(msg.data.length == 0); } /** * Adds new peer to list of signature verifiers. Can be called only by contract owner. * @param newAddress address of new peer */ function addPeer(address newAddress) private returns (uint) { require(isPeer[newAddress] == false); isPeer[newAddress] = true; ++peersCount; return peersCount; } function removePeer(address peerAddress) private { require(isPeer[peerAddress] == true); isPeer[peerAddress] = false; --peersCount; } function addPeerByPeer( address newPeerAddress, bytes32 txHash, uint8[] memory v, bytes32[] memory r, bytes32[] memory s ) public returns (bool) { require(used[txHash] == false); require(checkSignatures(keccak256(abi.encodePacked(newPeerAddress, txHash)), v, r, s) ); addPeer(newPeerAddress); used[txHash] = true; return true; } function removePeerByPeer( address peerAddress, bytes32 txHash, uint8[] memory v, bytes32[] memory r, bytes32[] memory s ) public returns (bool) { require(used[txHash] == false); require(checkSignatures( keccak256(abi.encodePacked(peerAddress, txHash)), v, r, s) ); removePeer(peerAddress); used[txHash] = true; return true; } /** * Adds new token to whitelist. Token should not been already added. * @param newToken token to add */ function addToken(address newToken) public onlyOwner { require(isToken[newToken] == false); isToken[newToken] = true; } /** * Checks is given token inside a whitelist or not * @param tokenAddress address of token to check * @return true if token inside whitelist or false otherwise */ function checkTokenAddress(address tokenAddress) public view returns (bool) { return isToken[tokenAddress]; } /** * Withdraws specified amount of ether or one of ERC-20 tokens to provided address * @param tokenAddress address of token to withdraw (0 for ether) * @param amount amount of tokens or ether to withdraw * @param to target account address * @param txHash hash of transaction from Iroha * @param v array of signatures of tx_hash (v-component) * @param r array of signatures of tx_hash (r-component) * @param s array of signatures of tx_hash (s-component) * @param from relay contract address */ function withdraw( address tokenAddress, uint256 amount, address payable to, bytes32 txHash, uint8[] memory v, bytes32[] memory r, bytes32[] memory s, address from ) public { require(checkTokenAddress(tokenAddress)); require(relayRegistryInstance.isWhiteListed(from, to)); require(used[txHash] == false); require(checkSignatures( keccak256(abi.encodePacked(tokenAddress, amount, to, txHash, from)), v, r, s) ); if (tokenAddress == address (0)) { if (address(this).balance < amount) { emit InsufficientFundsForWithdrawal(tokenAddress, to); } else { used[txHash] = true; // untrusted transfer, relies on provided cryptographic proof to.transfer(amount); } } else { IERC20 coin = IERC20(tokenAddress); if (coin.balanceOf(address (this)) < amount) { emit InsufficientFundsForWithdrawal(tokenAddress, to); } else { used[txHash] = true; // untrusted call, relies on provided cryptographic proof coin.transfer(to, amount); } } } /** * Checks given addresses for duplicates and if they are peers signatures * @param hash unsigned data * @param v v-component of signature from hash * @param r r-component of signature from hash * @param s s-component of signature from hash * @return true if all given addresses are correct or false otherwise */ function checkSignatures(bytes32 hash, uint8[] memory v, bytes32[] memory r, bytes32[] memory s ) private returns (bool) { require(peersCount >= 1); require(v.length == r.length); require(r.length == s.length); uint needSigs = peersCount - (peersCount - 1) / 3; require(s.length >= needSigs); uint count = 0; address[] memory recoveredAddresses = new address[](s.length); for (uint i = 0; i < s.length; ++i) { address recoveredAddress = recoverAddress( hash, v[i], r[i], s[i] ); // not a peer address or not unique if (isPeer[recoveredAddress] != true || uniqueAddresses[recoveredAddress] == true) { continue; } recoveredAddresses[count] = recoveredAddress; count = count + 1; uniqueAddresses[recoveredAddress] = true; } // restore state for future usages for (uint i = 0; i < count; ++i) { uniqueAddresses[recoveredAddresses[i]] = false; } return count >= needSigs; } /** * Recovers address from a given single signature * @param hash unsigned data * @param v v-component of signature from hash * @param r r-component of signature from hash * @param s s-component of signature from hash * @return address recovered from signature */ function recoverAddress(bytes32 hash, uint8 v, bytes32 r, bytes32 s) private pure returns (address) { bytes32 simple_hash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); address res = ecrecover(simple_hash, v, r, s); return res; } /** * Mint new XORToken * @param tokenAddress address to mint * @param amount how much to mint * @param beneficiary destination address * @param txHash hash of transaction from Iroha * @param v array of signatures of tx_hash (v-component) * @param r array of signatures of tx_hash (r-component) * @param s array of signatures of tx_hash (s-component) */ function mintTokensByPeers( address tokenAddress, uint256 amount, address beneficiary, bytes32 txHash, uint8[] memory v, bytes32[] memory r, bytes32[] memory s, address from ) public { require(address(xorTokenInstance) == tokenAddress); require(relayRegistryInstance.isWhiteListed(from, beneficiary)); require(used[txHash] == false); require(checkSignatures( keccak256(abi.encodePacked(tokenAddress, amount, beneficiary, txHash, from)), v, r, s) ); xorTokenInstance.mintTokens(beneficiary, amount); used[txHash] = true; } }
pragma solidity ^0.5.8; /** * @title Ownable * @dev The Ownable contract has an owner address, and provides basic authorization control * functions, this simplifies the implementation of "user permissions". */ contract Ownable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev The Ownable constructor sets the original `owner` of the contract to the sender * account. */ constructor () internal { _owner = msg.sender; emit OwnershipTransferred(address(0), _owner); } /** * @return the address of the owner. */ function owner() public view returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(isOwner()); _; } /** * @return true if `msg.sender` is the owner of the contract. */ function isOwner() public view returns (bool) { return msg.sender == _owner; } /** * @dev Allows the current owner to relinquish control of the contract. * @notice Renouncing to ownership will leave the contract without an owner. * It will not be possible to call the functions with the `onlyOwner` * modifier anymore. */ function renounceOwnership() public onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Allows the current owner to transfer control of the contract to a newOwner. * @param newOwner The address to transfer ownership to. */ function transferOwnership(address newOwner) public onlyOwner { _transferOwnership(newOwner); } /** * @dev Transfers control of the contract to a newOwner. * @param newOwner The address to transfer ownership to. */ function _transferOwnership(address newOwner) internal { require(newOwner != address(0)); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } }
pragma solidity ^0.5.8; import './UpgradeabilityProxy.sol'; /** * @title OwnedUpgradeabilityProxy * @dev This contract combines an upgradeability proxy with basic authorization control functionalities */ contract OwnedUpgradeabilityProxy is UpgradeabilityProxy { /** * @dev Event to show ownership has been transferred * @param previousOwner representing the address of the previous owner * @param newOwner representing the address of the new owner */ event ProxyOwnershipTransferred(address previousOwner, address newOwner); // Storage position of the owner of the contract bytes32 private constant proxyOwnerPosition = keccak256("com.d3ledger.proxy.owner"); /** * @dev the constructor sets the original owner of the contract to the sender account. */ constructor() public { setUpgradeabilityOwner(msg.sender); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyProxyOwner() { require(msg.sender == proxyOwner()); _; } /** * @dev Tells the address of the owner * @return the address of the owner */ function proxyOwner() public view returns (address owner) { bytes32 position = proxyOwnerPosition; assembly { owner := sload(position) } } /** * @dev Sets the address of the owner */ function setUpgradeabilityOwner(address newProxyOwner) internal { bytes32 position = proxyOwnerPosition; assembly { sstore(position, newProxyOwner) } } /** * @dev Allows the current owner to transfer control of the contract to a newOwner. * @param newOwner The address to transfer ownership to. */ function transferProxyOwnership(address newOwner) public onlyProxyOwner { require(newOwner != address(0)); emit ProxyOwnershipTransferred(proxyOwner(), newOwner); setUpgradeabilityOwner(newOwner); } /** * @dev Allows the proxy owner to upgrade the current version of the proxy. * @param implementation representing the address of the new implementation to be set. */ function upgradeTo(address implementation) public onlyProxyOwner { _upgradeTo(implementation); } /** * @dev Allows the proxy owner to upgrade the current version of the proxy and call the new implementation * to initialize whatever is needed through a low level call. * @param implementation representing the address of the new implementation to be set. * @param data represents the msg.data to bet sent in the low level call. This parameter may include the function * signature of the implementation to be called with the needed payload */ function upgradeToAndCall(address implementation, bytes memory data) payable public onlyProxyOwner { upgradeTo(implementation); (bool success,) = address(this).call.value(msg.value)(data); require(success); } }
pragma solidity ^0.5.8; /** * @title Proxy * @dev Gives the possibility to delegate any call to a foreign implementation. */ contract Proxy { /** * @dev Tells the address of the implementation where every call will be delegated. * @return address of the implementation to which it will be delegated */ function implementation() public view returns (address); /** * @dev Fallback function allowing to perform a delegatecall to the given implementation. * This function will return whatever the implementation call returns */ function () payable external { address _impl = implementation(); require(_impl != address(0)); assembly { let ptr := mload(0x40) calldatacopy(ptr, 0, calldatasize) let result := delegatecall(gas, _impl, ptr, calldatasize, 0, 0) let size := returndatasize returndatacopy(ptr, 0, size) switch result case 0 { revert(ptr, size) } default { return(ptr, size) } } } }
pragma solidity ^0.5.8; import "./IMaster.sol"; import "./IERC20.sol"; /** * Provides functionality of relay contract */ contract Relay { bool internal initialized_; address payable private masterAddress; IMaster private masterInstance; event AddressEvent(address input); event StringEvent(string input); event BytesEvent(bytes32 input); event NumberEvent(uint256 input); /** * Relay constructor * @param master address of master contract */ constructor(address payable master) public { initialize(master); } /** * Initialization of smart contract. */ function initialize(address payable master) public { require(!initialized_); masterAddress = master; masterInstance = IMaster(masterAddress); initialized_ = true; } /** * A special function-like stub to allow ether accepting */ function() external payable { require(msg.data.length == 0); emit AddressEvent(msg.sender); } /** * Sends ether and all tokens from this contract to master * @param tokenAddress address of sending token (0 for Ether) */ function sendToMaster(address tokenAddress) public { // trusted call require(masterInstance.checkTokenAddress(tokenAddress)); if (tokenAddress == address(0)) { // trusted transfer masterAddress.transfer(address(this).balance); } else { IERC20 ic = IERC20(tokenAddress); // untrusted call in general but coin addresses are received from trusted master contract // which contains and manages whitelist of them ic.transfer(masterAddress, ic.balanceOf(address(this))); } } /** * Withdraws specified amount of ether or one of ERC-20 tokens to provided address * @param tokenAddress address of token to withdraw (0 for ether) * @param amount amount of tokens or ether to withdraw * @param to target account address * @param tx_hash hash of transaction from Iroha * @param v array of signatures of tx_hash (v-component) * @param r array of signatures of tx_hash (r-component) * @param s array of signatures of tx_hash (s-component) * @param from relay contract address */ function withdraw( address tokenAddress, uint256 amount, address payable to, bytes32 tx_hash, uint8[] memory v, bytes32[] memory r, bytes32[] memory s, address from ) public { emit AddressEvent(masterAddress); // trusted call masterInstance.withdraw(tokenAddress, amount, to, tx_hash, v, r, s, from); } /** * Mint specified amount of ether or one of ERC-20 tokens to provided address * @param tokenAddress address to mint * @param amount how much to mint * @param beneficiary destination address * @param txHash hash of transaction from Iroha * @param v array of signatures of tx_hash (v-component) * @param r array of signatures of tx_hash (r-component) * @param s array of signatures of tx_hash (s-component) * @param from relay contract address */ function mintTokensByPeers( address tokenAddress, uint256 amount, address beneficiary, bytes32 txHash, uint8[] memory v, bytes32[] memory r, bytes32[] memory s, address from ) public { emit AddressEvent(masterAddress); // trusted call masterInstance.mintTokensByPeers(tokenAddress, amount, beneficiary, txHash, v, r, s, from); } }
pragma solidity ^0.5.8; import "./IRelayRegistry.sol"; /** * @title Relay registry store data about white list and provide interface for master */ contract RelayRegistry is IRelayRegistry { bool internal initialized_; address private owner_; mapping(address => address[]) private _relayWhiteList; constructor () public { initialize(msg.sender); } /** * Initialization of smart contract. */ function initialize(address owner) public { require(!initialized_); owner_ = owner; initialized_ = true; } /** * Store relay address and appropriate whitelist of addresses * @param relay contract address * @param whiteList white list */ function addNewRelayAddress(address relay, address[] calldata whiteList) external { require(msg.sender == owner_); require(_relayWhiteList[relay].length == 0); _relayWhiteList[relay] = whiteList; emit AddNewRelay(relay, whiteList); } /** * Check if some address is in the whitelist * @param relay contract address * @param who address in whitelist * @return true if address in the whitelist */ function isWhiteListed(address relay, address who) external view returns (bool) { if (_relayWhiteList[relay].length == 0) { return true; } if (_relayWhiteList[relay].length > 0) { for (uint i = 0; i < _relayWhiteList[relay].length; i++) { if (who == _relayWhiteList[relay][i]) { return true; } } } return false; } /** * Get entire whitelist by relay address * @param relay contract address * @return array of the whitelist */ function getWhiteListByRelay(address relay) external view returns (address[] memory ) { require(relay != address(0)); require(_relayWhiteList[relay].length != 0); return _relayWhiteList[relay]; } }
pragma solidity ^0.5.8; /** * @title SafeMath * @dev Unsigned math operations with safety checks that revert on error */ library SafeMath { /** * @dev Multiplies two unsigned integers, reverts on overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b); return c; } /** * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend). */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a); uint256 c = a - b; return c; } /** * @dev Adds two unsigned integers, reverts on overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a); return c; } /** * @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo), * reverts when dividing by zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0); return a % b; } }
pragma solidity ^0.5.8; contract TestGreeter_v0 { bool ininialized_; string greeting_; constructor(string memory greeting) public { initialize(greeting); } function initialize(string memory greeting) public { require(!ininialized_); greeting_ = greeting; ininialized_ = true; } function greet() view public returns (string memory) { return greeting_; } function set(string memory greeting) public { greeting_ = greeting; } }
pragma solidity ^0.5.8; import './TestGreeter_v0.sol'; contract TestGreeter_v1 is TestGreeter_v0("Hi, World!") { function farewell() public view returns (string memory) { return "Good bye!"; } }
pragma solidity ^0.5.8; /** * Contract that sends Ether with internal transaction for testing purposes. */ contract TransferEthereum { /** * A special function-like stub to allow ether accepting */ function() external payable { require(msg.data.length == 0); } function transfer(address payable to, uint256 amount) public { to.call.value(amount)(""); } }
pragma solidity ^0.5.8; import './Proxy.sol'; /** * @title UpgradeabilityProxy * @dev This contract represents a proxy where the implementation address to which it will delegate can be upgraded */ contract UpgradeabilityProxy is Proxy { /** * @dev This event will be emitted every time the implementation gets upgraded * @param implementation representing the address of the upgraded implementation */ event Upgraded(address indexed implementation); // Storage position of the address of the current implementation bytes32 private constant implementationPosition = keccak256("com.d3ledger.proxy.implementation"); /** * @dev Constructor function */ constructor() public {} /** * @dev Tells the address of the current implementation * @return address of the current implementation */ function implementation() public view returns (address impl) { bytes32 position = implementationPosition; assembly { impl := sload(position) } } /** * @dev Sets the address of the current implementation * @param newImplementation address representing the new implementation to be set */ function setImplementation(address newImplementation) internal { bytes32 position = implementationPosition; assembly { sstore(position, newImplementation) } } /** * @dev Upgrades the implementation address * @param newImplementation representing the address of the new implementation to be set */ function _upgradeTo(address newImplementation) internal { address currentImplementation = implementation(); require(currentImplementation != newImplementation); setImplementation(newImplementation); emit Upgraded(newImplementation); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"INITIAL_SUPPLY","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"value","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"value","type":"uint256"}],"name":"burnFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"},{"name":"spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"beneficiary","type":"address"},{"name":"amount","type":"uint256"}],"name":"mintTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"}]
Contract Creation Code
60806040523480156200001157600080fd5b506040518060400160405280600a81526020017f536f726120546f6b656e000000000000000000000000000000000000000000008152506040518060400160405280600381526020017f584f520000000000000000000000000000000000000000000000000000000000815250601282600390805190602001906200009892919062000204565b508151620000ae90600490602085019062000204565b506005805460ff191660ff9290921691909117610100600160a81b03191661010033810291909117918290556040516001600160a01b0391909204169250600091507f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a36200012b3360006001600160e01b036200013116565b620002a9565b6001600160a01b0382166200014557600080fd5b6200016181600254620001ea60201b620008901790919060201c565b6002556001600160a01b038216600090815260208181526040909120546200019491839062000890620001ea821b17901c565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600082820183811015620001fd57600080fd5b9392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200024757805160ff191683800117855562000277565b8280016001018555821562000277579182015b82811115620002775782518255916020019190600101906200025a565b506200028592915062000289565b5090565b620002a691905b8082111562000285576000815560010162000290565b90565b610aec80620002b96000396000f3fe608060405234801561001057600080fd5b50600436106101215760003560e01c8063715018a6116100ad578063a457c2d711610071578063a457c2d714610332578063a9059cbb1461035e578063dd62ed3e1461038a578063f0dda65c146103b8578063f2fde38b146103e457610121565b8063715018a6146102ca57806379cc6790146102d25780638da5cb5b146102fe5780638f32d59b1461032257806395d89b411461032a57610121565b80632ff2e9dc116100f45780632ff2e9dc14610233578063313ce5671461023b578063395093511461025957806342966c681461028557806370a08231146102a457610121565b806306fdde0314610126578063095ea7b3146101a357806318160ddd146101e357806323b872dd146101fd575b600080fd5b61012e61040a565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610168578181015183820152602001610150565b50505050905090810190601f1680156101955780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101cf600480360360408110156101b957600080fd5b506001600160a01b0381351690602001356104a0565b604080519115158252519081900360200190f35b6101eb6104b6565b60408051918252519081900360200190f35b6101cf6004803603606081101561021357600080fd5b506001600160a01b038135811691602081013590911690604001356104bc565b6101eb610513565b610243610518565b6040805160ff9092168252519081900360200190f35b6101cf6004803603604081101561026f57600080fd5b506001600160a01b038135169060200135610521565b6102a26004803603602081101561029b57600080fd5b503561055d565b005b6101eb600480360360208110156102ba57600080fd5b50356001600160a01b031661056a565b6102a2610585565b6102a2600480360360408110156102e857600080fd5b506001600160a01b0381351690602001356105e6565b6103066105f4565b604080516001600160a01b039092168252519081900360200190f35b6101cf610608565b61012e61061e565b6101cf6004803603604081101561034857600080fd5b506001600160a01b03813516906020013561067f565b6101cf6004803603604081101561037457600080fd5b506001600160a01b0381351690602001356106bb565b6101eb600480360360408110156103a057600080fd5b506001600160a01b03813581169160200135166106c8565b6102a2600480360360408110156103ce57600080fd5b506001600160a01b0381351690602001356106f3565b6102a2600480360360208110156103fa57600080fd5b50356001600160a01b031661070e565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104965780601f1061046b57610100808354040283529160200191610496565b820191906000526020600020905b81548152906001019060200180831161047957829003601f168201915b5050505050905090565b60006104ad338484610728565b50600192915050565b60025490565b60006104c98484846107b0565b6001600160a01b038416600090815260016020908152604080832033808552925290912054610509918691610504908663ffffffff61087b16565b610728565b5060019392505050565b600081565b60055460ff1690565b3360008181526001602090815260408083206001600160a01b038716845290915281205490916104ad918590610504908663ffffffff61089016565b61056733826108a9565b50565b6001600160a01b031660009081526020819052604090205490565b61058d610608565b61059657600080fd5b60055460405160009161010090046001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a360058054610100600160a81b0319169055565b6105f08282610950565b5050565b60055461010090046001600160a01b031690565b60055461010090046001600160a01b0316331490565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104965780601f1061046b57610100808354040283529160200191610496565b3360008181526001602090815260408083206001600160a01b038716845290915281205490916104ad918590610504908663ffffffff61087b16565b60006104ad3384846107b0565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6106fb610608565b61070457600080fd5b6105f08282610995565b610716610608565b61071f57600080fd5b61056781610a3d565b6001600160a01b03821661073b57600080fd5b6001600160a01b03831661074e57600080fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b0382166107c357600080fd5b6001600160a01b0383166000908152602081905260409020546107ec908263ffffffff61087b16565b6001600160a01b038085166000908152602081905260408082209390935590841681522054610821908263ffffffff61089016565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008282111561088a57600080fd5b50900390565b6000828201838110156108a257600080fd5b9392505050565b6001600160a01b0382166108bc57600080fd5b6002546108cf908263ffffffff61087b16565b6002556001600160a01b0382166000908152602081905260409020546108fb908263ffffffff61087b16565b6001600160a01b038316600081815260208181526040808320949094558351858152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35050565b61095a82826108a9565b6001600160a01b0382166000908152600160209081526040808320338085529252909120546105f0918491610504908563ffffffff61087b16565b6001600160a01b0382166109a857600080fd5b6002546109bb908263ffffffff61089016565b6002556001600160a01b0382166000908152602081905260409020546109e7908263ffffffff61089016565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b6001600160a01b038116610a5057600080fd5b6005546040516001600160a01b0380841692610100900416907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600580546001600160a01b0390921661010002610100600160a81b031990921691909117905556fea265627a7a72305820332223d26ddabcb0063e47e2563255a244ad435fb5313e225d08e2c9862bdb6564736f6c63430005090032
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101215760003560e01c8063715018a6116100ad578063a457c2d711610071578063a457c2d714610332578063a9059cbb1461035e578063dd62ed3e1461038a578063f0dda65c146103b8578063f2fde38b146103e457610121565b8063715018a6146102ca57806379cc6790146102d25780638da5cb5b146102fe5780638f32d59b1461032257806395d89b411461032a57610121565b80632ff2e9dc116100f45780632ff2e9dc14610233578063313ce5671461023b578063395093511461025957806342966c681461028557806370a08231146102a457610121565b806306fdde0314610126578063095ea7b3146101a357806318160ddd146101e357806323b872dd146101fd575b600080fd5b61012e61040a565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610168578181015183820152602001610150565b50505050905090810190601f1680156101955780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101cf600480360360408110156101b957600080fd5b506001600160a01b0381351690602001356104a0565b604080519115158252519081900360200190f35b6101eb6104b6565b60408051918252519081900360200190f35b6101cf6004803603606081101561021357600080fd5b506001600160a01b038135811691602081013590911690604001356104bc565b6101eb610513565b610243610518565b6040805160ff9092168252519081900360200190f35b6101cf6004803603604081101561026f57600080fd5b506001600160a01b038135169060200135610521565b6102a26004803603602081101561029b57600080fd5b503561055d565b005b6101eb600480360360208110156102ba57600080fd5b50356001600160a01b031661056a565b6102a2610585565b6102a2600480360360408110156102e857600080fd5b506001600160a01b0381351690602001356105e6565b6103066105f4565b604080516001600160a01b039092168252519081900360200190f35b6101cf610608565b61012e61061e565b6101cf6004803603604081101561034857600080fd5b506001600160a01b03813516906020013561067f565b6101cf6004803603604081101561037457600080fd5b506001600160a01b0381351690602001356106bb565b6101eb600480360360408110156103a057600080fd5b506001600160a01b03813581169160200135166106c8565b6102a2600480360360408110156103ce57600080fd5b506001600160a01b0381351690602001356106f3565b6102a2600480360360208110156103fa57600080fd5b50356001600160a01b031661070e565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104965780601f1061046b57610100808354040283529160200191610496565b820191906000526020600020905b81548152906001019060200180831161047957829003601f168201915b5050505050905090565b60006104ad338484610728565b50600192915050565b60025490565b60006104c98484846107b0565b6001600160a01b038416600090815260016020908152604080832033808552925290912054610509918691610504908663ffffffff61087b16565b610728565b5060019392505050565b600081565b60055460ff1690565b3360008181526001602090815260408083206001600160a01b038716845290915281205490916104ad918590610504908663ffffffff61089016565b61056733826108a9565b50565b6001600160a01b031660009081526020819052604090205490565b61058d610608565b61059657600080fd5b60055460405160009161010090046001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a360058054610100600160a81b0319169055565b6105f08282610950565b5050565b60055461010090046001600160a01b031690565b60055461010090046001600160a01b0316331490565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104965780601f1061046b57610100808354040283529160200191610496565b3360008181526001602090815260408083206001600160a01b038716845290915281205490916104ad918590610504908663ffffffff61087b16565b60006104ad3384846107b0565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6106fb610608565b61070457600080fd5b6105f08282610995565b610716610608565b61071f57600080fd5b61056781610a3d565b6001600160a01b03821661073b57600080fd5b6001600160a01b03831661074e57600080fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b0382166107c357600080fd5b6001600160a01b0383166000908152602081905260409020546107ec908263ffffffff61087b16565b6001600160a01b038085166000908152602081905260408082209390935590841681522054610821908263ffffffff61089016565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008282111561088a57600080fd5b50900390565b6000828201838110156108a257600080fd5b9392505050565b6001600160a01b0382166108bc57600080fd5b6002546108cf908263ffffffff61087b16565b6002556001600160a01b0382166000908152602081905260409020546108fb908263ffffffff61087b16565b6001600160a01b038316600081815260208181526040808320949094558351858152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35050565b61095a82826108a9565b6001600160a01b0382166000908152600160209081526040808320338085529252909120546105f0918491610504908563ffffffff61087b16565b6001600160a01b0382166109a857600080fd5b6002546109bb908263ffffffff61089016565b6002556001600160a01b0382166000908152602081905260409020546109e7908263ffffffff61089016565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b6001600160a01b038116610a5057600080fd5b6005546040516001600160a01b0380841692610100900416907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600580546001600160a01b0390921661010002610100600160a81b031990921691909117905556fea265627a7a72305820332223d26ddabcb0063e47e2563255a244ad435fb5313e225d08e2c9862bdb6564736f6c63430005090032
Deployed Bytecode Sourcemap
110:438:16:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;110:438:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;628:81:3;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;628:81:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2723:145:1;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;2723:145:1;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;924:89;;;:::i;:::-;;;;;;;;;;;;;;;;3331:224;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;3331:224:1;;;;;;;;;;;;;;;;;:::i;177:42:16:-;;;:::i;930:81:3:-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;4058:200:1;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;4058:200:1;;;;;;;;:::i;295:77:2:-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;295:77:2;;:::i;:::-;;1222:104:1;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1222:104:1;-1:-1:-1;;;;;1222:104:1;;:::i;1347:137:10:-;;;:::i;624:93:2:-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;624:93:2;;;;;;;;:::i;659:77:10:-;;;:::i;:::-;;;;-1:-1:-1;;;;;659:77:10;;;;;;;;;;;;;;979:90;;;:::i;771:85:3:-;;;:::i;4766:210:1:-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;4766:210:1;;;;;;;;:::i;1950:137::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;1950:137:1;;;;;;;;:::i;1657:129::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;1657:129:1;;;;;;;;;;:::i;428:117:16:-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;428:117:16;;;;;;;;:::i;1655:107:10:-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1655:107:10;-1:-1:-1;;;;;1655:107:10;;:::i;628:81:3:-;697:5;690:12;;;;;;;;-1:-1:-1;;690:12:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;665:13;;690:12;;697:5;;690:12;;697:5;690:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;628:81;:::o;2723:145:1:-;2788:4;2804:36;2813:10;2825:7;2834:5;2804:8;:36::i;:::-;-1:-1:-1;2857:4:1;2723:145;;;;:::o;924:89::-;994:12;;924:89;:::o;3331:224::-;3410:4;3426:26;3436:4;3442:2;3446:5;3426:9;:26::i;:::-;-1:-1:-1;;;;;3489:14:1;;;;;;-1:-1:-1;3489:14:1;;;;;;;;3477:10;3489:26;;;;;;;;;3462:65;;3489:14;;:37;;3520:5;3489:30;:37::i;:::-;3462:8;:65::i;:::-;-1:-1:-1;3544:4:1;3331:224;;;;;:::o;177:42:16:-;218:1;177:42;:::o;930:81:3:-;995:9;;;;930:81;:::o;4058:200:1:-;4163:10;4138:4;4184:20;;;:8;:20;;;;;;;;-1:-1:-1;;;;;4184:29:1;;;;;;;;;;4138:4;;4154:76;;4184:29;;:45;;4218:10;4184:33;:45::i;295:77:2:-;341:24;347:10;359:5;341;:24::i;:::-;295:77;:::o;1222:104:1:-;-1:-1:-1;;;;;1303:16:1;1277:7;1303:16;;;;;;;;;;;;1222:104::o;1347:137:10:-;863:9;:7;:9::i;:::-;855:18;;;;;;1429:6;;1408:40;;1445:1;;1429:6;;;-1:-1:-1;;;;;1429:6:10;;1408:40;;1445:1;;1408:40;1458:6;:19;;-1:-1:-1;;;;;;1458:19:10;;;1347:137::o;624:93:2:-;688:22;698:4;704:5;688:9;:22::i;:::-;624:93;;:::o;659:77:10:-;723:6;;;;;-1:-1:-1;;;;;723:6:10;;659:77::o;979:90::-;1056:6;;;;;-1:-1:-1;;;;;1056:6:10;1042:10;:20;;979:90::o;771:85:3:-;842:7;835:14;;;;;;;;-1:-1:-1;;835:14:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;810:13;;835:14;;842:7;;835:14;;842:7;835:14;;;;;;;;;;;;;;;;;;;;;;;;4766:210:1;4876:10;4851:4;4897:20;;;:8;:20;;;;;;;;-1:-1:-1;;;;;4897:29:1;;;;;;;;;;4851:4;;4867:81;;4897:29;;:50;;4931:15;4897:33;:50::i;1950:137::-;2011:4;2027:32;2037:10;2049:2;2053:5;2027:9;:32::i;1657:129::-;-1:-1:-1;;;;;1755:15:1;;;1729:7;1755:15;;;-1:-1:-1;1755:15:1;;;;;;;;:24;;;;;;;;;;;;;1657:129::o;428:117:16:-;863:9:10;:7;:9::i;:::-;855:18;;;;;;512:26:16;518:11;531:6;512:5;:26::i;1655:107:10:-;863:9;:7;:9::i;:::-;855:18;;;;;;1727:28;1746:8;1727:18;:28::i;6806:248:1:-;-1:-1:-1;;;;;6898:21:1;;6890:30;;;;;;-1:-1:-1;;;;;6938:19:1;;6930:28;;;;;;-1:-1:-1;;;;;6969:15:1;;;;;;;-1:-1:-1;6969:15:1;;;;;;;;:24;;;;;;;;;;;;;:32;;;7016:31;;;;;;;;;;;;;;;;;6806:248;;;:::o;5190:256::-;-1:-1:-1;;;;;5277:16:1;;5269:25;;;;;;-1:-1:-1;;;;;5323:15:1;;:9;:15;;;;;;;;;;;:26;;5343:5;5323:19;:26::i;:::-;-1:-1:-1;;;;;5305:15:1;;;:9;:15;;;;;;;;;;;:44;;;;5375:13;;;;;;;:24;;5393:5;5375:17;:24::i;:::-;-1:-1:-1;;;;;5359:13:1;;;:9;:13;;;;;;;;;;;;:40;;;;5414:25;;;;;;;5359:13;;5414:25;;;;;;;;;;;;;5190:256;;;:::o;1205:145:15:-;1263:7;1295:1;1290;:6;;1282:15;;;;;;-1:-1:-1;1319:5:15;;;1205:145::o;1431:::-;1489:7;1520:5;;;1543:6;;;;1535:15;;;;;;1568:1;1431:145;-1:-1:-1;;;1431:145:15:o;6278:263:1:-;-1:-1:-1;;;;;6352:21:1;;6344:30;;;;;;6400:12;;:23;;6417:5;6400:23;:16;:23;:::i;:::-;6385:12;:38;-1:-1:-1;;;;;6454:18:1;;:9;:18;;;;;;;;;;;:29;;6477:5;6454:22;:29::i;:::-;-1:-1:-1;;;;;6433:18:1;;:9;:18;;;;;;;;;;;:50;;;;6498:36;;;;;;;6433:9;;6498:36;;;;;;;;;;;6278:263;;:::o;7443:179::-;7513:21;7519:7;7528:5;7513;:21::i;:::-;-1:-1:-1;;;;;7574:17:1;;;;;;-1:-1:-1;7574:17:1;;;;;;;;7562:10;7574:29;;;;;;;;;7544:71;;7574:17;;:40;;7608:5;7574:33;:40::i;5789:263::-;-1:-1:-1;;;;;5863:21:1;;5855:30;;;;;;5911:12;;:23;;5928:5;5911:23;:16;:23;:::i;:::-;5896:12;:38;-1:-1:-1;;;;;5965:18:1;;:9;:18;;;;;;;;;;;:29;;5988:5;5965:22;:29::i;:::-;-1:-1:-1;;;;;5944:18:1;;:9;:18;;;;;;;;;;;:50;;;;6009:36;;;;;;;5944:18;;:9;;6009:36;;;;;;;;;;5789:263;;:::o;1906:183:10:-;-1:-1:-1;;;;;1979:22:10;;1971:31;;;;;;2038:6;;2017:38;;-1:-1:-1;;;;;2017:38:10;;;;2038:6;;;;;2017:38;;;;;2065:6;:17;;-1:-1:-1;;;;;2065:17:10;;;;;;-1:-1:-1;;;;;;2065:17:10;;;;;;;;;1906:183::o
Swarm Source
bzzr://332223d26ddabcb0063e47e2563255a244ad435fb5313e225d08e2c9862bdb65
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.