Overview
ETH Balance
0 ETH
Eth Value
$0.00Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x1e928fbd921b4a3214b58432c2057e78b86044d1688d9dc7f74dcc213bbc0e96 | Approve | (pending) | 2 days ago | IN | 0 ETH | (Pending) | |||
0x7b4aab8942cb95bf85bfb096c5cd2669c4323c8da12c1795034b7a90d0c37c76 | Approve | (pending) | 18 days ago | IN | 0 ETH | (Pending) | |||
Transfer | 21472456 | 12 hrs ago | IN | 0 ETH | 0.00066226 | ||||
Approve | 21465420 | 35 hrs ago | IN | 0 ETH | 0.00052407 | ||||
Approve | 21464418 | 39 hrs ago | IN | 0 ETH | 0.00052844 | ||||
Approve | 21458745 | 2 days ago | IN | 0 ETH | 0.00059098 | ||||
Transfer | 21458556 | 2 days ago | IN | 0 ETH | 0.00041883 | ||||
Approve | 21456493 | 2 days ago | IN | 0 ETH | 0.00047113 | ||||
Approve | 21435293 | 5 days ago | IN | 0 ETH | 0.00061781 | ||||
Approve | 21434016 | 5 days ago | IN | 0 ETH | 0.00077325 | ||||
Approve | 21431377 | 6 days ago | IN | 0 ETH | 0.00127479 | ||||
Approve | 21431334 | 6 days ago | IN | 0 ETH | 0.00101091 | ||||
Approve | 21424923 | 7 days ago | IN | 0 ETH | 0.00062238 | ||||
Approve | 21423520 | 7 days ago | IN | 0 ETH | 0.00173703 | ||||
Approve | 21422070 | 7 days ago | IN | 0 ETH | 0.00052309 | ||||
Approve | 21420527 | 7 days ago | IN | 0 ETH | 0.00063666 | ||||
Transfer | 21420378 | 7 days ago | IN | 0 ETH | 0.00089088 | ||||
Transfer Ownersh... | 21420363 | 7 days ago | IN | 0 ETH | 0.00046604 | ||||
Set Controller | 21420362 | 7 days ago | IN | 0 ETH | 0.0004553 | ||||
Claim Ownership | 21419891 | 7 days ago | IN | 0 ETH | 0.00025281 | ||||
Transfer | 21418350 | 8 days ago | IN | 0 ETH | 0.00115563 | ||||
Mint To | 21416402 | 8 days ago | IN | 0 ETH | 0.00215371 | ||||
Mint To | 21416100 | 8 days ago | IN | 0 ETH | 0.00182751 | ||||
Transfer | 21415342 | 8 days ago | IN | 0 ETH | 0.00080059 | ||||
Mint To | 21414901 | 8 days ago | IN | 0 ETH | 0.00098911 |
Advanced mode: Intended for advanced users or developers and will display all Internal Transactions including zero value transfers. Name tag integration is not available in advanced view.
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
||||
---|---|---|---|---|---|---|---|
21475159 | 2 hrs ago | 0 ETH | |||||
21475159 | 2 hrs ago | 0 ETH | |||||
21475159 | 2 hrs ago | 0 ETH | |||||
21475159 | 2 hrs ago | 0 ETH | |||||
21475159 | 2 hrs ago | 0 ETH | |||||
21475159 | 2 hrs ago | 0 ETH | |||||
21473036 | 10 hrs ago | 0 ETH | |||||
21473036 | 10 hrs ago | 0 ETH | |||||
21473036 | 10 hrs ago | 0 ETH | |||||
21473036 | 10 hrs ago | 0 ETH | |||||
21472456 | 12 hrs ago | 0 ETH | |||||
21472330 | 12 hrs ago | 0 ETH | |||||
21472330 | 12 hrs ago | 0 ETH | |||||
21472330 | 12 hrs ago | 0 ETH | |||||
21472330 | 12 hrs ago | 0 ETH | |||||
21472172 | 12 hrs ago | 0 ETH | |||||
21472172 | 12 hrs ago | 0 ETH | |||||
21472172 | 12 hrs ago | 0 ETH | |||||
21472172 | 12 hrs ago | 0 ETH | |||||
21472165 | 13 hrs ago | 0 ETH | |||||
21472165 | 13 hrs ago | 0 ETH | |||||
21472165 | 13 hrs ago | 0 ETH | |||||
21472165 | 13 hrs ago | 0 ETH | |||||
21472165 | 13 hrs ago | 0 ETH | |||||
21472165 | 13 hrs ago | 0 ETH |
Loading...
Loading
Contract Name:
EUR
Compiler Version
v0.4.24+commit.e67f0147
Optimization Enabled:
Yes with 1000 runs
Other Settings:
default evmVersion, Apache-2.0 license, Audited
Contract Source Code (Solidity)Audit Report
/** *Submitted for verification at Etherscan.io on 2019-11-11 */ // File: openzeppelin-solidity/contracts/ownership/Ownable.sol pragma solidity ^0.4.24; /** * @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 public owner; event OwnershipRenounced(address indexed previousOwner); event OwnershipTransferred( address indexed previousOwner, address indexed newOwner ); /** * @dev The Ownable constructor sets the original `owner` of the contract to the sender * account. */ constructor() public { owner = msg.sender; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(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 OwnershipRenounced(owner); 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; } } // File: openzeppelin-solidity/contracts/ownership/Claimable.sol pragma solidity ^0.4.24; /** * @title Claimable * @dev Extension for the Ownable contract, where the ownership needs to be claimed. * This allows the new owner to accept the transfer. */ contract Claimable is Ownable { address public pendingOwner; /** * @dev Modifier throws if called by any account other than the pendingOwner. */ modifier onlyPendingOwner() { require(msg.sender == pendingOwner); _; } /** * @dev Allows the current owner to set the pendingOwner address. * @param newOwner The address to transfer ownership to. */ function transferOwnership(address newOwner) public onlyOwner { pendingOwner = newOwner; } /** * @dev Allows the pendingOwner address to finalize the transfer. */ function claimOwnership() public onlyPendingOwner { emit OwnershipTransferred(owner, pendingOwner); owner = pendingOwner; pendingOwner = address(0); } } // File: openzeppelin-solidity/contracts/token/ERC20/ERC20Basic.sol pragma solidity ^0.4.24; /** * @title ERC20Basic * @dev Simpler version of ERC20 interface * See https://github.com/ethereum/EIPs/issues/179 */ contract ERC20Basic { function totalSupply() public view returns (uint256); function balanceOf(address _who) public view returns (uint256); function transfer(address _to, uint256 _value) public returns (bool); event Transfer(address indexed from, address indexed to, uint256 value); } // File: openzeppelin-solidity/contracts/token/ERC20/ERC20.sol pragma solidity ^0.4.24; /** * @title ERC20 interface * @dev see https://github.com/ethereum/EIPs/issues/20 */ contract ERC20 is ERC20Basic { function allowance(address _owner, address _spender) public view returns (uint256); function transferFrom(address _from, address _to, uint256 _value) public returns (bool); function approve(address _spender, uint256 _value) public returns (bool); event Approval( address indexed owner, address indexed spender, uint256 value ); } // File: openzeppelin-solidity/contracts/token/ERC20/SafeERC20.sol pragma solidity ^0.4.24; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure. * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { function safeTransfer( ERC20Basic _token, address _to, uint256 _value ) internal { require(_token.transfer(_to, _value)); } function safeTransferFrom( ERC20 _token, address _from, address _to, uint256 _value ) internal { require(_token.transferFrom(_from, _to, _value)); } function safeApprove( ERC20 _token, address _spender, uint256 _value ) internal { require(_token.approve(_spender, _value)); } } // File: openzeppelin-solidity/contracts/ownership/CanReclaimToken.sol pragma solidity ^0.4.24; /** * @title Contracts that should be able to recover tokens * @author SylTi * @dev This allow a contract to recover any ERC20 token received in a contract by transferring the balance to the contract owner. * This will prevent any accidental loss of tokens. */ contract CanReclaimToken is Ownable { using SafeERC20 for ERC20Basic; /** * @dev Reclaim all ERC20Basic compatible tokens * @param _token ERC20Basic The address of the token contract */ function reclaimToken(ERC20Basic _token) external onlyOwner { uint256 balance = _token.balanceOf(this); _token.safeTransfer(owner, balance); } } // File: openzeppelin-solidity/contracts/ownership/HasNoEther.sol pragma solidity ^0.4.24; /** * @title Contracts that should not own Ether * @author Remco Bloemen <remco@2π.com> * @dev This tries to block incoming ether to prevent accidental loss of Ether. Should Ether end up * in the contract, it will allow the owner to reclaim this Ether. * @notice Ether can still be sent to this contract by: * calling functions labeled `payable` * `selfdestruct(contract_address)` * mining directly to the contract address */ contract HasNoEther is Ownable { /** * @dev Constructor that rejects incoming Ether * The `payable` flag is added so we can access `msg.value` without compiler warning. If we * leave out payable, then Solidity will allow inheriting contracts to implement a payable * constructor. By doing it this way we prevent a payable constructor from working. Alternatively * we could use assembly to access msg.value. */ constructor() public payable { require(msg.value == 0); } /** * @dev Disallows direct send by setting a default function without the `payable` flag. */ function() external { } /** * @dev Transfer all Ether held by the contract to the owner. */ function reclaimEther() external onlyOwner { owner.transfer(address(this).balance); } } // File: openzeppelin-solidity/contracts/ownership/HasNoTokens.sol pragma solidity ^0.4.24; /** * @title Contracts that should not own Tokens * @author Remco Bloemen <remco@2π.com> * @dev This blocks incoming ERC223 tokens to prevent accidental loss of tokens. * Should tokens (any ERC20Basic compatible) end up in the contract, it allows the * owner to reclaim the tokens. */ contract HasNoTokens is CanReclaimToken { /** * @dev Reject all ERC223 compatible tokens * @param _from address The address that is transferring the tokens * @param _value uint256 the amount of the specified token * @param _data Bytes The data passed from the caller. */ function tokenFallback( address _from, uint256 _value, bytes _data ) external pure { _from; _value; _data; revert(); } } // File: openzeppelin-solidity/contracts/ownership/HasNoContracts.sol pragma solidity ^0.4.24; /** * @title Contracts that should not own Contracts * @author Remco Bloemen <remco@2π.com> * @dev Should contracts (anything Ownable) end up being owned by this contract, it allows the owner * of this contract to reclaim ownership of the contracts. */ contract HasNoContracts is Ownable { /** * @dev Reclaim ownership of Ownable contracts * @param _contractAddr The address of the Ownable to be reclaimed. */ function reclaimContract(address _contractAddr) external onlyOwner { Ownable contractInst = Ownable(_contractAddr); contractInst.transferOwnership(owner); } } // File: openzeppelin-solidity/contracts/ownership/NoOwner.sol pragma solidity ^0.4.24; /** * @title Base contract for contracts that should not own things. * @author Remco Bloemen <remco@2π.com> * @dev Solves a class of errors where a contract accidentally becomes owner of Ether, Tokens or * Owned contracts. See respective base contracts for details. */ contract NoOwner is HasNoEther, HasNoTokens, HasNoContracts { } // File: openzeppelin-solidity/contracts/lifecycle/Destructible.sol pragma solidity ^0.4.24; /** * @title Destructible * @dev Base contract that can be destroyed by owner. All funds in contract will be sent to the owner. */ contract Destructible is Ownable { /** * @dev Transfers the current balance to the owner and terminates the contract. */ function destroy() public onlyOwner { selfdestruct(owner); } function destroyAndSend(address _recipient) public onlyOwner { selfdestruct(_recipient); } } // File: contracts/IERC20.sol /** * Copyright 2019 Monerium ehf. * * 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.4.24; /** * @dev Interface of the ERC20 standard as defined in the EIP. Does not include * the optional functions; to access them see `ERC20Detailed`. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a `Transfer` event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through `transferFrom`. This is * zero by default. * * This value changes when `approve` or `transferFrom` are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * > 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 * * Emits an `Approval` event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a `Transfer` event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to `approve`. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } // File: openzeppelin-solidity/contracts/math/SafeMath.sol pragma solidity ^0.4.24; /** * @title SafeMath * @dev Math operations with safety checks that throw on error */ library SafeMath { /** * @dev Multiplies two numbers, throws on overflow. */ function mul(uint256 _a, uint256 _b) internal pure returns (uint256 c) { // Gas optimization: this is cheaper than asserting '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; } c = _a * _b; assert(c / _a == _b); return c; } /** * @dev Integer division of two numbers, truncating the quotient. */ function div(uint256 _a, uint256 _b) internal pure returns (uint256) { // assert(_b > 0); // Solidity automatically throws when dividing by 0 // uint256 c = _a / _b; // assert(_a == _b * c + _a % _b); // There is no case in which this doesn't hold return _a / _b; } /** * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). */ function sub(uint256 _a, uint256 _b) internal pure returns (uint256) { assert(_b <= _a); return _a - _b; } /** * @dev Adds two numbers, throws on overflow. */ function add(uint256 _a, uint256 _b) internal pure returns (uint256 c) { c = _a + _b; assert(c >= _a); return c; } } // File: contracts/TokenStorageLib.sol /** * Copyright 2019 Monerium ehf. * * 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.4.24; /** @title TokenStorageLib * @dev Implementation of an[external storage for tokens. */ library TokenStorageLib { using SafeMath for uint; struct TokenStorage { mapping (address => uint) balances; mapping (address => mapping (address => uint)) allowed; uint totalSupply; } /** * @dev Increases balance of an address. * @param self Token storage to operate on. * @param to Address to increase. * @param amount Number of units to add. */ function addBalance(TokenStorage storage self, address to, uint amount) external { self.totalSupply = self.totalSupply.add(amount); self.balances[to] = self.balances[to].add(amount); } /** * @dev Decreases balance of an address. * @param self Token storage to operate on. * @param from Address to decrease. * @param amount Number of units to subtract. */ function subBalance(TokenStorage storage self, address from, uint amount) external { self.totalSupply = self.totalSupply.sub(amount); self.balances[from] = self.balances[from].sub(amount); } /** * @dev Sets the allowance for a spender. * @param self Token storage to operate on. * @param owner Address of the owner of the tokens to spend. * @param spender Address of the spender. * @param amount Qunatity of allowance. */ function setAllowed(TokenStorage storage self, address owner, address spender, uint amount) external { self.allowed[owner][spender] = amount; } /** * @dev Returns the supply of tokens. * @param self Token storage to operate on. * @return Total supply. */ function getSupply(TokenStorage storage self) external view returns (uint) { return self.totalSupply; } /** * @dev Returns the balance of an address. * @param self Token storage to operate on. * @param who Address to lookup. * @return Number of units. */ function getBalance(TokenStorage storage self, address who) external view returns (uint) { return self.balances[who]; } /** * @dev Returns the allowance for a spender. * @param self Token storage to operate on. * @param owner Address of the owner of the tokens to spend. * @param spender Address of the spender. * @return Number of units. */ function getAllowed(TokenStorage storage self, address owner, address spender) external view returns (uint) { return self.allowed[owner][spender]; } } // File: contracts/TokenStorage.sol /** * Copyright 2019 Monerium ehf. * * 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.4.24; /** * @title TokenStorage * @dev External storage for tokens. * The storage is implemented in a separate contract to maintain state * between token upgrades. */ contract TokenStorage is Claimable, CanReclaimToken, NoOwner { using TokenStorageLib for TokenStorageLib.TokenStorage; TokenStorageLib.TokenStorage internal tokenStorage; /** * @dev Increases balance of an address. * @param to Address to increase. * @param amount Number of units to add. */ function addBalance(address to, uint amount) external onlyOwner { tokenStorage.addBalance(to, amount); } /** * @dev Decreases balance of an address. * @param from Address to decrease. * @param amount Number of units to subtract. */ function subBalance(address from, uint amount) external onlyOwner { tokenStorage.subBalance(from, amount); } /** * @dev Sets the allowance for a spender. * @param owner Address of the owner of the tokens to spend. * @param spender Address of the spender. * @param amount Qunatity of allowance. */ function setAllowed(address owner, address spender, uint amount) external onlyOwner { tokenStorage.setAllowed(owner, spender, amount); } /** * @dev Returns the supply of tokens. * @return Total supply. */ function getSupply() external view returns (uint) { return tokenStorage.getSupply(); } /** * @dev Returns the balance of an address. * @param who Address to lookup. * @return Number of units. */ function getBalance(address who) external view returns (uint) { return tokenStorage.getBalance(who); } /** * @dev Returns the allowance for a spender. * @param owner Address of the owner of the tokens to spend. * @param spender Address of the spender. * @return Number of units. */ function getAllowed(address owner, address spender) external view returns (uint) { return tokenStorage.getAllowed(owner, spender); } } // File: contracts/ERC20Lib.sol /** * Copyright 2019 Monerium ehf. * * 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.4.24; /** * @title ERC20Lib * @dev Standard ERC20 token functionality. * https://github.com/ethereum/EIPs/issues/20 */ library ERC20Lib { using SafeMath for uint; /** * @dev Transfers tokens [ERC20]. * @param db Token storage to operate on. * @param caller Address of the caller passed through the frontend. * @param to Recipient address. * @param amount Number of tokens to transfer. */ function transfer(TokenStorage db, address caller, address to, uint amount) external returns (bool success) { db.subBalance(caller, amount); db.addBalance(to, amount); return true; } /** * @dev Transfers tokens from a specific address [ERC20]. * The address owner has to approve the spender beforehand. * @param db Token storage to operate on. * @param caller Address of the caller passed through the frontend. * @param from Address to debet the tokens from. * @param to Recipient address. * @param amount Number of tokens to transfer. */ function transferFrom( TokenStorage db, address caller, address from, address to, uint amount ) external returns (bool success) { uint allowance = db.getAllowed(from, caller); db.subBalance(from, amount); db.addBalance(to, amount); db.setAllowed(from, caller, allowance.sub(amount)); return true; } /** * @dev Approves a spender [ERC20]. * Note that using the approve/transferFrom presents a possible * security vulnerability described in: * https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/edit#heading=h.quou09mcbpzw * Use transferAndCall to mitigate. * @param db Token storage to operate on. * @param caller Address of the caller passed through the frontend. * @param spender The address of the future spender. * @param amount The allowance of the spender. */ function approve(TokenStorage db, address caller, address spender, uint amount) public returns (bool success) { db.setAllowed(caller, spender, amount); return true; } /** * @dev Returns the number tokens associated with an address. * @param db Token storage to operate on. * @param who Address to lookup. * @return Balance of address. */ function balanceOf(TokenStorage db, address who) external view returns (uint balance) { return db.getBalance(who); } /** * @dev Returns the allowance for a spender * @param db Token storage to operate on. * @param owner The address of the owner of the tokens. * @param spender The address of the spender. * @return Number of tokens the spender is allowed to spend. */ function allowance(TokenStorage db, address owner, address spender) external view returns (uint remaining) { return db.getAllowed(owner, spender); } } // File: contracts/MintableTokenLib.sol /** * Copyright 2019 Monerium ehf. * * 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.4.24; /** * @title Mintable token * @dev Simple ERC20 Token example, with mintable token creation * @dev Issue: * https://github.com/OpenZeppelin/openzeppelin-solidity/issues/120 * Based on code by TokenMarketNet: https://github.com/TokenMarketNet/ico/blob/master/contracts/MintableToken.sol */ library MintableTokenLib { using SafeMath for uint; /** * @dev Mints new tokens. * @param db Token storage to operate on. * @param to The address that will recieve the minted tokens. * @param amount The amount of tokens to mint. */ function mint( TokenStorage db, address to, uint amount ) external returns (bool) { db.addBalance(to, amount); return true; } /** * @dev Burns tokens. * @param db Token storage to operate on. * @param from The address holding tokens. * @param amount The amount of tokens to burn. */ function burn( TokenStorage db, address from, uint amount ) public returns (bool) { db.subBalance(from, amount); return true; } /** * @dev Burns tokens from a specific address. * To burn the tokens the caller needs to provide a signature * proving that the caller is authorized by the token owner to do so. * @param db Token storage to operate on. * @param from The address holding tokens. * @param amount The amount of tokens to burn. * @param h Hash which the token owner signed. * @param v Signature component. * @param r Signature component. * @param s Sigature component. */ function burn( TokenStorage db, address from, uint amount, bytes32 h, uint8 v, bytes32 r, bytes32 s ) external returns (bool) { require( ecrecover(h, v, r, s) == from, "signature/hash does not match" ); return burn(db, from, amount); } } // File: contracts/IValidator.sol /** * Copyright 2019 Monerium ehf. * * 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.4.24; /** * @title IValidator * @dev Contracts implementing this interface validate token transfers. */ interface IValidator { /** * @dev Emitted when a validator makes a decision. * @param from Sender address. * @param to Recipient address. * @param amount Number of tokens. * @param valid True if transfer approved, false if rejected. */ event Decision(address indexed from, address indexed to, uint amount, bool valid); /** * @dev Validates token transfer. * If the sender is on the blacklist the transfer is denied. * @param from Sender address. * @param to Recipient address. * @param amount Number of tokens. */ function validate(address from, address to, uint amount) external returns (bool valid); } // File: contracts/SmartTokenLib.sol /** * Copyright 2019 Monerium ehf. * * 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.4.24; /** * @title SmartTokenLib * @dev This library provides functionality which is required from a regulatory perspective. */ library SmartTokenLib { using ERC20Lib for TokenStorage; using MintableTokenLib for TokenStorage; struct SmartStorage { IValidator validator; } /** * @dev Emitted when the contract owner recovers tokens. * @param from Sender address. * @param to Recipient address. * @param amount Number of tokens. */ event Recovered(address indexed from, address indexed to, uint amount); /** * @dev Emitted when updating the validator. * @param old Address of the old validator. * @param current Address of the new validator. */ event Validator(address indexed old, address indexed current); /** * @dev Sets a new validator. * @param self Smart storage to operate on. * @param validator Address of validator. */ function setValidator(SmartStorage storage self, address validator) external { emit Validator(self.validator, validator); self.validator = IValidator(validator); } /** * @dev Approves or rejects a transfer request. * The request is forwarded to a validator which implements * the actual business logic. * @param self Smart storage to operate on. * @param from Sender address. * @param to Recipient address. * @param amount Number of tokens. */ function validate(SmartStorage storage self, address from, address to, uint amount) external returns (bool valid) { return self.validator.validate(from, to, amount); } /** * @dev Recovers tokens from an address and reissues them to another address. * In case a user loses its private key the tokens can be recovered by burning * the tokens from that address and reissuing to a new address. * To recover tokens the contract owner needs to provide a signature * proving that the token owner has authorized the owner to do so. * @param from Address to burn tokens from. * @param to Address to mint tokens to. * @param h Hash which the token owner signed. * @param v Signature component. * @param r Signature component. * @param s Sigature component. * @return Amount recovered. */ function recover( TokenStorage token, address from, address to, bytes32 h, uint8 v, bytes32 r, bytes32 s ) external returns (uint) { require( ecrecover(h, v, r, s) == from, "signature/hash does not recover from address" ); uint amount = token.balanceOf(from); token.burn(from, amount); token.mint(to, amount); emit Recovered(from, to, amount); return amount; } /** * @dev Gets the current validator. * @param self Smart storage to operate on. * @return Address of validator. */ function getValidator(SmartStorage storage self) external view returns (address) { return address(self.validator); } } // File: openzeppelin-solidity/contracts/lifecycle/Pausable.sol pragma solidity ^0.4.24; /** * @title Pausable * @dev Base contract which allows children to implement an emergency stop mechanism. */ contract Pausable is Ownable { event Pause(); event Unpause(); bool public paused = false; /** * @dev Modifier to make a function callable only when the contract is not paused. */ modifier whenNotPaused() { require(!paused); _; } /** * @dev Modifier to make a function callable only when the contract is paused. */ modifier whenPaused() { require(paused); _; } /** * @dev called by the owner to pause, triggers stopped state */ function pause() public onlyOwner whenNotPaused { paused = true; emit Pause(); } /** * @dev called by the owner to unpause, returns to normal state */ function unpause() public onlyOwner whenPaused { paused = false; emit Unpause(); } } // File: openzeppelin-solidity/contracts/AddressUtils.sol pragma solidity ^0.4.24; /** * Utility library of inline functions on addresses */ library AddressUtils { /** * Returns whether the target address is a contract * @dev This function will return false if invoked during the constructor of a contract, * as the code is not actually created until after the constructor finishes. * @param _addr address to check * @return whether the target address is a contract */ function isContract(address _addr) internal view returns (bool) { uint256 size; // XXX Currently there is no better way to check if there is a contract in an address // than to check the size of the code at that address. // See https://ethereum.stackexchange.com/a/14016/36603 // for more details about how this works. // TODO Check this again before the Serenity release, because all addresses will be // contracts then. // solium-disable-next-line security/no-inline-assembly assembly { size := extcodesize(_addr) } return size > 0; } } // File: contracts/IERC677Recipient.sol /** * Copyright 2019 Monerium ehf. * * 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.4.24; /** * @title IERC677Recipient * @dev Contracts implementing this interface can participate in [ERC677]. */ interface IERC677Recipient { /** * @dev Receives notification from [ERC677] transferAndCall. * @param from Sender address. * @param amount Number of tokens. * @param data Additional data. */ function onTokenTransfer(address from, uint256 amount, bytes data) external returns (bool); } // File: contracts/ERC677Lib.sol /** * Copyright 2019 Monerium ehf. * * 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.4.24; /** * @title ERC677 * @dev ERC677 token functionality. * https://github.com/ethereum/EIPs/issues/677 */ library ERC677Lib { using ERC20Lib for TokenStorage; using AddressUtils for address; /** * @dev Transfers tokens and subsequently calls a method on the recipient [ERC677]. * If the recipient is a non-contract address this method behaves just like transfer. * @notice db.transfer either returns true or reverts. * @param db Token storage to operate on. * @param caller Address of the caller passed through the frontend. * @param to Recipient address. * @param amount Number of tokens to transfer. * @param data Additional data passed to the recipient's tokenFallback method. */ function transferAndCall( TokenStorage db, address caller, address to, uint256 amount, bytes data ) external returns (bool) { require( db.transfer(caller, to, amount), "unable to transfer" ); if (to.isContract()) { IERC677Recipient recipient = IERC677Recipient(to); require( recipient.onTokenTransfer(caller, amount, data), "token handler returns false" ); } return true; } } // File: contracts/StandardController.sol /** * Copyright 2019 Monerium ehf. * * 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.4.24; /** * @title StandardController * @dev This is the base contract which delegates token methods [ERC20 and ERC677] * to their respective library implementations. * The controller is primarily intended to be interacted with via a token frontend. */ contract StandardController is Pausable, Destructible, Claimable { using ERC20Lib for TokenStorage; using ERC677Lib for TokenStorage; TokenStorage internal token; address internal frontend; string public name; string public symbol; uint public decimals = 18; /** * @dev Emitted when updating the frontend. * @param old Address of the old frontend. * @param current Address of the new frontend. */ event Frontend(address indexed old, address indexed current); /** * @dev Emitted when updating the storage. * @param old Address of the old storage. * @param current Address of the new storage. */ event Storage(address indexed old, address indexed current); /** * @dev Modifier which prevents the function from being called by unauthorized parties. * The caller must either be the sender or the function must be * called via the frontend, otherwise the call is reverted. * @param caller The address of the passed-in caller. Used to preserve the original caller. */ modifier guarded(address caller) { require( msg.sender == caller || msg.sender == frontend, "either caller must be sender or calling via frontend" ); _; } /** * @dev Contract constructor. * @param storage_ Address of the token storage for the controller. * @param initialSupply The amount of tokens to mint upon creation. * @param frontend_ Address of the authorized frontend. */ constructor(address storage_, uint initialSupply, address frontend_) public { require( storage_ == 0x0 || initialSupply == 0, "either a token storage must be initialized or no initial supply" ); if (storage_ == 0x0) { token = new TokenStorage(); token.addBalance(msg.sender, initialSupply); } else { token = TokenStorage(storage_); } frontend = frontend_; } /** * @dev Prevents tokens to be sent to well known blackholes by throwing on known blackholes. * @param to The address of the intended recipient. */ function avoidBlackholes(address to) internal view { require(to != 0x0, "must not send to 0x0"); require(to != address(this), "must not send to controller"); require(to != address(token), "must not send to token storage"); require(to != frontend, "must not send to frontend"); } /** * @dev Returns the current frontend. * @return Address of the frontend. */ function getFrontend() external view returns (address) { return frontend; } /** * @dev Returns the current storage. * @return Address of the storage. */ function getStorage() external view returns (address) { return address(token); } /** * @dev Sets a new frontend. * @param frontend_ Address of the new frontend. */ function setFrontend(address frontend_) public onlyOwner { emit Frontend(frontend, frontend_); frontend = frontend_; } /** * @dev Sets a new storage. * @param storage_ Address of the new storage. */ function setStorage(address storage_) external onlyOwner { emit Storage(address(token), storage_); token = TokenStorage(storage_); } /** * @dev Transfers the ownership of the storage. * @param newOwner Address of the new storage owner. */ function transferStorageOwnership(address newOwner) public onlyOwner { token.transferOwnership(newOwner); } /** * @dev Claims the ownership of the storage. */ function claimStorageOwnership() public onlyOwner { token.claimOwnership(); } /** * @dev Transfers tokens [ERC20]. * @param caller Address of the caller passed through the frontend. * @param to Recipient address. * @param amount Number of tokens to transfer. */ function transfer_withCaller(address caller, address to, uint amount) public guarded(caller) whenNotPaused returns (bool ok) { avoidBlackholes(to); return token.transfer(caller, to, amount); } /** * @dev Transfers tokens from a specific address [ERC20]. * The address owner has to approve the spender beforehand. * @param caller Address of the caller passed through the frontend. * @param from Address to debet the tokens from. * @param to Recipient address. * @param amount Number of tokens to transfer. */ function transferFrom_withCaller(address caller, address from, address to, uint amount) public guarded(caller) whenNotPaused returns (bool ok) { avoidBlackholes(to); return token.transferFrom(caller, from, to, amount); } /** * @dev Approves a spender [ERC20]. * Note that using the approve/transferFrom presents a possible * security vulnerability described in: * https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/edit#heading=h.quou09mcbpzw * Use transferAndCall to mitigate. * @param caller Address of the caller passed through the frontend. * @param spender The address of the future spender. * @param amount The allowance of the spender. */ function approve_withCaller(address caller, address spender, uint amount) public guarded(caller) whenNotPaused returns (bool ok) { return token.approve(caller, spender, amount); } /** * @dev Transfers tokens and subsequently calls a method on the recipient [ERC677]. * If the recipient is a non-contract address this method behaves just like transfer. * @param caller Address of the caller passed through the frontend. * @param to Recipient address. * @param amount Number of tokens to transfer. * @param data Additional data passed to the recipient's tokenFallback method. */ function transferAndCall_withCaller( address caller, address to, uint256 amount, bytes data ) public guarded(caller) whenNotPaused returns (bool ok) { avoidBlackholes(to); return token.transferAndCall(caller, to, amount, data); } /** * @dev Returns the total supply. * @return Number of tokens. */ function totalSupply() external view returns (uint) { return token.getSupply(); } /** * @dev Returns the number tokens associated with an address. * @param who Address to lookup. * @return Balance of address. */ function balanceOf(address who) external view returns (uint) { return token.getBalance(who); } /** * @dev Returns the allowance for a spender * @param owner The address of the owner of the tokens. * @param spender The address of the spender. * @return Number of tokens the spender is allowed to spend. */ function allowance(address owner, address spender) external view returns (uint) { return token.allowance(owner, spender); } } // File: openzeppelin-solidity/contracts/access/rbac/Roles.sol pragma solidity ^0.4.24; /** * @title Roles * @author Francisco Giordano (@frangio) * @dev Library for managing addresses assigned to a Role. * See RBAC.sol for example usage. */ library Roles { struct Role { mapping (address => bool) bearer; } /** * @dev give an address access to this role */ function add(Role storage _role, address _addr) internal { _role.bearer[_addr] = true; } /** * @dev remove an address' access to this role */ function remove(Role storage _role, address _addr) internal { _role.bearer[_addr] = false; } /** * @dev check if an address has this role * // reverts */ function check(Role storage _role, address _addr) internal view { require(has(_role, _addr)); } /** * @dev check if an address has this role * @return bool */ function has(Role storage _role, address _addr) internal view returns (bool) { return _role.bearer[_addr]; } } // File: contracts/SystemRole.sol /** * Copyright 2019 Monerium ehf. * * 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.4.24; /** * @title SystemRole * @dev SystemRole accounts have been approved to perform operational actions (e.g. mint and burn). * @notice addSystemAccount and removeSystemAccount are unprotected by default, i.e. anyone can call them. * @notice Contracts inheriting SystemRole *should* authorize the caller by overriding them. */ contract SystemRole { using Roles for Roles.Role; Roles.Role private systemAccounts; /** * @dev Emitted when system account is added. * @param account is a new system account. */ event SystemAccountAdded(address indexed account); /** * @dev Emitted when system account is removed. * @param account is the old system account. */ event SystemAccountRemoved(address indexed account); /** * @dev Modifier which prevents non-system accounts from calling protected functions. */ modifier onlySystemAccounts() { require(isSystemAccount(msg.sender)); _; } /** * @dev Modifier which prevents non-system accounts from being passed to the guard. * @param account The account to check. */ modifier onlySystemAccount(address account) { require( isSystemAccount(account), "must be a system account" ); _; } /** * @dev System Role constructor. * @notice The contract is an abstract contract as a result of the internal modifier. */ constructor() internal {} /** * @dev Checks whether an address is a system account. * @param account the address to check. * @return true if system account. */ function isSystemAccount(address account) public view returns (bool) { return systemAccounts.has(account); } /** * @dev Assigns the system role to an account. * @notice This method is unprotected and should be authorized in the child contract. */ function addSystemAccount(address account) public { systemAccounts.add(account); emit SystemAccountAdded(account); } /** * @dev Removes the system role from an account. * @notice This method is unprotected and should be authorized in the child contract. */ function removeSystemAccount(address account) public { systemAccounts.remove(account); emit SystemAccountRemoved(account); } } // File: contracts/MintableController.sol /** * Copyright 2019 Monerium ehf. * * 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.4.24; /** * @title MintableController * @dev This contracts implements functionality allowing for minting and burning of tokens. */ contract MintableController is SystemRole, StandardController { using MintableTokenLib for TokenStorage; /** * @dev Contract constructor. * @param storage_ Address of the token storage for the controller. * @param initialSupply The amount of tokens to mint upon creation. * @param frontend_ Address of the authorized frontend. */ constructor(address storage_, uint initialSupply, address frontend_) public StandardController(storage_, initialSupply, frontend_) { } /** * @dev Assigns the system role to an account. */ function addSystemAccount(address account) public onlyOwner { super.addSystemAccount(account); } /** * @dev Removes the system role from an account. */ function removeSystemAccount(address account) public onlyOwner { super.removeSystemAccount(account); } /** * @dev Mints new tokens. * @param caller Address of the caller passed through the frontend. * @param to Address to credit the tokens. * @param amount Number of tokens to mint. */ function mintTo_withCaller(address caller, address to, uint amount) public guarded(caller) onlySystemAccount(caller) returns (bool) { avoidBlackholes(to); return token.mint(to, amount); } /** * @dev Burns tokens from token owner. * This removfes the burned tokens from circulation. * @param caller Address of the caller passed through the frontend. * @param from Address of the token owner. * @param amount Number of tokens to burn. * @param h Hash which the token owner signed. * @param v Signature component. * @param r Signature component. * @param s Sigature component. */ function burnFrom_withCaller(address caller, address from, uint amount, bytes32 h, uint8 v, bytes32 r, bytes32 s) public guarded(caller) onlySystemAccount(caller) returns (bool) { return token.burn(from, amount, h, v, r, s); } } // File: contracts/SmartController.sol /** * Copyright 2019 Monerium ehf. * * 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.4.24; /** * @title SmartController * @dev This contract adds "smart" functionality which is required from a regulatory perspective. */ contract SmartController is MintableController { using SmartTokenLib for SmartTokenLib.SmartStorage; SmartTokenLib.SmartStorage internal smartToken; bytes3 public ticker; uint constant public INITIAL_SUPPLY = 0; /** * @dev Contract constructor. * @param storage_ Address of the token storage for the controller. * @param validator Address of validator. * @param ticker_ 3 letter currency ticker. * @param frontend_ Address of the authorized frontend. */ constructor(address storage_, address validator, bytes3 ticker_, address frontend_) public MintableController(storage_, INITIAL_SUPPLY, frontend_) { require(validator != 0x0, "validator cannot be the null address"); smartToken.setValidator(validator); ticker = ticker_; } /** * @dev Sets a new validator. * @param validator Address of validator. */ function setValidator(address validator) external onlySystemAccounts { smartToken.setValidator(validator); } /** * @dev Recovers tokens from an address and reissues them to another address. * In case a user loses its private key the tokens can be recovered by burning * the tokens from that address and reissuing to a new address. * To recover tokens the contract owner needs to provide a signature * proving that the token owner has authorized the owner to do so. * @param caller Address of the caller passed through the frontend. * @param from Address to burn tokens from. * @param to Address to mint tokens to. * @param h Hash which the token owner signed. * @param v Signature component. * @param r Signature component. * @param s Sigature component. * @return Amount recovered. */ function recover_withCaller(address caller, address from, address to, bytes32 h, uint8 v, bytes32 r, bytes32 s) external guarded(caller) onlySystemAccount(caller) returns (uint) { avoidBlackholes(to); return SmartTokenLib.recover(token, from, to, h, v, r, s); } /** * @dev Transfers tokens [ERC20]. * The caller, to address and amount are validated before executing method. * Prior to transfering tokens the validator needs to approve. * @notice Overrides method in a parent. * @param caller Address of the caller passed through the frontend. * @param to Recipient address. * @param amount Number of tokens to transfer. */ function transfer_withCaller(address caller, address to, uint amount) public guarded(caller) whenNotPaused returns (bool) { require(smartToken.validate(caller, to, amount), "transfer request not valid"); return super.transfer_withCaller(caller, to, amount); } /** * @dev Transfers tokens from a specific address [ERC20]. * The address owner has to approve the spender beforehand. * The from address, to address and amount are validated before executing method. * @notice Overrides method in a parent. * Prior to transfering tokens the validator needs to approve. * @param caller Address of the caller passed through the frontend. * @param from Address to debet the tokens from. * @param to Recipient address. * @param amount Number of tokens to transfer. */ function transferFrom_withCaller(address caller, address from, address to, uint amount) public guarded(caller) whenNotPaused returns (bool) { require(smartToken.validate(from, to, amount), "transferFrom request not valid"); return super.transferFrom_withCaller(caller, from, to, amount); } /** * @dev Transfers tokens and subsequently calls a method on the recipient [ERC677]. * If the recipient is a non-contract address this method behaves just like transfer. * The caller, to address and amount are validated before executing method. * @notice Overrides method in a parent. * @param caller Address of the caller passed through the frontend. * @param to Recipient address. * @param amount Number of tokens to transfer. * @param data Additional data passed to the recipient's tokenFallback method. */ function transferAndCall_withCaller( address caller, address to, uint256 amount, bytes data ) public guarded(caller) whenNotPaused returns (bool) { require(smartToken.validate(caller, to, amount), "transferAndCall request not valid"); return super.transferAndCall_withCaller(caller, to, amount, data); } /** * @dev Gets the current validator. * @return Address of validator. */ function getValidator() external view returns (address) { return smartToken.getValidator(); } } // File: contracts/TokenFrontend.sol /** * Copyright 2019 Monerium ehf. * * 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.4.24; /** * @title TokenFrontend * @dev This contract implements a token forwarder. * The token frontend is [ERC20 and ERC677] compliant and forwards * standard methods to a controller. The primary function is to allow * for a statically deployed contract for users to interact with while * simultaneously allow the controllers to be upgraded when bugs are * discovered or new functionality needs to be added. */ contract TokenFrontend is Destructible, Claimable, CanReclaimToken, NoOwner, IERC20 { SmartController internal controller; string public name; string public symbol; bytes3 public ticker; /** * @dev Emitted when tokens are transferred. * @param from Sender address. * @param to Recipient address. * @param amount Number of tokens transferred. */ event Transfer(address indexed from, address indexed to, uint amount); /** * @dev Emitted when tokens are transferred. * @param from Sender address. * @param to Recipient address. * @param amount Number of tokens transferred. * @param data Additional data passed to the recipient's tokenFallback method. */ event Transfer(address indexed from, address indexed to, uint amount, bytes data); /** * @dev Emitted when spender is granted an allowance. * @param owner Address of the owner of the tokens to spend. * @param spender The address of the future spender. * @param amount The allowance of the spender. */ event Approval(address indexed owner, address indexed spender, uint amount); /** * @dev Emitted when updating the controller. * @param ticker Three letter ticker representing the currency. * @param old Address of the old controller. * @param current Address of the new controller. */ event Controller(bytes3 indexed ticker, address indexed old, address indexed current); /** * @dev Contract constructor. * @notice The contract is an abstract contract as a result of the internal modifier. * @param name_ Token name. * @param symbol_ Token symbol. * @param ticker_ 3 letter currency ticker. */ constructor(string name_, string symbol_, bytes3 ticker_) internal { name = name_; symbol = symbol_; ticker = ticker_; } /** * @dev Sets a new controller. * @param address_ Address of the controller. */ function setController(address address_) external onlyOwner { require(address_ != 0x0, "controller address cannot be the null address"); emit Controller(ticker, controller, address_); controller = SmartController(address_); require(controller.getFrontend() == address(this), "controller frontend does not point back"); require(controller.ticker() == ticker, "ticker does not match controller ticket"); } /** * @dev Transfers tokens [ERC20]. * @param to Recipient address. * @param amount Number of tokens to transfer. */ function transfer(address to, uint amount) external returns (bool ok) { ok = controller.transfer_withCaller(msg.sender, to, amount); emit Transfer(msg.sender, to, amount); } /** * @dev Transfers tokens from a specific address [ERC20]. * The address owner has to approve the spender beforehand. * @param from Address to debet the tokens from. * @param to Recipient address. * @param amount Number of tokens to transfer. */ function transferFrom(address from, address to, uint amount) external returns (bool ok) { ok = controller.transferFrom_withCaller(msg.sender, from, to, amount); emit Transfer(from, to, amount); } /** * @dev Approves a spender [ERC20]. * Note that using the approve/transferFrom presents a possible * security vulnerability described in: * https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/edit#heading=h.quou09mcbpzw * Use transferAndCall to mitigate. * @param spender The address of the future spender. * @param amount The allowance of the spender. */ function approve(address spender, uint amount) external returns (bool ok) { ok = controller.approve_withCaller(msg.sender, spender, amount); emit Approval(msg.sender, spender, amount); } /** * @dev Transfers tokens and subsequently calls a method on the recipient [ERC677]. * If the recipient is a non-contract address this method behaves just like transfer. * @param to Recipient address. * @param amount Number of tokens to transfer. * @param data Additional data passed to the recipient's tokenFallback method. */ function transferAndCall(address to, uint256 amount, bytes data) external returns (bool ok) { ok = controller.transferAndCall_withCaller(msg.sender, to, amount, data); emit Transfer(msg.sender, to, amount); emit Transfer(msg.sender, to, amount, data); } /** * @dev Mints new tokens. * @param to Address to credit the tokens. * @param amount Number of tokens to mint. */ function mintTo(address to, uint amount) external returns (bool ok) { ok = controller.mintTo_withCaller(msg.sender, to, amount); emit Transfer(0x0, to, amount); } /** * @dev Burns tokens from token owner. * This removfes the burned tokens from circulation. * @param from Address of the token owner. * @param amount Number of tokens to burn. * @param h Hash which the token owner signed. * @param v Signature component. * @param r Signature component. * @param s Sigature component. */ function burnFrom(address from, uint amount, bytes32 h, uint8 v, bytes32 r, bytes32 s) external returns (bool ok) { ok = controller.burnFrom_withCaller(msg.sender, from, amount, h, v, r, s); emit Transfer(from, 0x0, amount); } /** * @dev Recovers tokens from an address and reissues them to another address. * In case a user loses its private key the tokens can be recovered by burning * the tokens from that address and reissuing to a new address. * To recover tokens the contract owner needs to provide a signature * proving that the token owner has authorized the owner to do so. * @param from Address to burn tokens from. * @param to Address to mint tokens to. * @param h Hash which the token owner signed. * @param v Signature component. * @param r Signature component. * @param s Sigature component. * @return Amount recovered. */ function recover(address from, address to, bytes32 h, uint8 v, bytes32 r, bytes32 s) external returns (uint amount) { amount = controller.recover_withCaller(msg.sender, from, to, h ,v, r, s); emit Transfer(from, to, amount); } /** * @dev Gets the current controller. * @return Address of the controller. */ function getController() external view returns (address) { return address(controller); } /** * @dev Returns the total supply. * @return Number of tokens. */ function totalSupply() external view returns (uint) { return controller.totalSupply(); } /** * @dev Returns the number tokens associated with an address. * @param who Address to lookup. * @return Balance of address. */ function balanceOf(address who) external view returns (uint) { return controller.balanceOf(who); } /** * @dev Returns the allowance for a spender * @param owner The address of the owner of the tokens. * @param spender The address of the spender. * @return Number of tokens the spender is allowed to spend. */ function allowance(address owner, address spender) external view returns (uint) { return controller.allowance(owner, spender); } /** * @dev Returns the number of decimals in one token. * @return Number of decimals. */ function decimals() external view returns (uint) { return controller.decimals(); } } // File: contracts/EUR.sol /** * Copyright 2019 Monerium ehf. * * 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.4.24; contract EUR is TokenFrontend { constructor() public TokenFrontend("Monerium EUR emoney", "EURe", "EUR") { } }
Contract Security Audit
- Ackee Blockchain- Aug 22nd, 2023 - Security Audit Report
[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"amount","type":"uint256"}],"name":"approve","outputs":[{"name":"ok","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"}],"name":"reclaimToken","outputs":[],"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":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"ok","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_contractAddr","type":"address"}],"name":"reclaimContract","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getController","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"amount","type":"uint256"},{"name":"h","type":"bytes32"},{"name":"v","type":"uint8"},{"name":"r","type":"bytes32"},{"name":"s","type":"bytes32"}],"name":"burnFrom","outputs":[{"name":"ok","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"amount","type":"uint256"},{"name":"data","type":"bytes"}],"name":"transferAndCall","outputs":[{"name":"ok","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"amount","type":"uint256"}],"name":"mintTo","outputs":[{"name":"ok","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"claimOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"h","type":"bytes32"},{"name":"v","type":"uint8"},{"name":"r","type":"bytes32"},{"name":"s","type":"bytes32"}],"name":"recover","outputs":[{"name":"amount","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"who","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":"destroy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"ticker","outputs":[{"name":"","type":"bytes3"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"address_","type":"address"}],"name":"setController","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"reclaimEther","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"name":"ok","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_from","type":"address"},{"name":"_value","type":"uint256"},{"name":"_data","type":"bytes"}],"name":"tokenFallback","outputs":[],"payable":false,"stateMutability":"pure","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":true,"inputs":[],"name":"pendingOwner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_recipient","type":"address"}],"name":"destroyAndSend","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":false,"stateMutability":"nonpayable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"data","type":"bytes"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"ticker","type":"bytes3"},{"indexed":true,"name":"old","type":"address"},{"indexed":true,"name":"current","type":"address"}],"name":"Controller","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"}],"name":"OwnershipRenounced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"}]
Contract Creation Code
60806040523480156200001157600080fd5b50604080518082018252601381527f4d6f6e657269756d2045555220656d6f6e6579000000000000000000000000006020808301919091528251808401909352600483527f45555265000000000000000000000000000000000000000000000000000000009083015260008054600160a060020a03191633179055907f45555200000000000000000000000000000000000000000000000000000000003415620000ba57600080fd5b8251620000cf90600390602086019062000121565b508151620000e590600490602085019062000121565b506005805462ffffff19167d01000000000000000000000000000000000000000000000000000000000090920491909117905550620001c69050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200016457805160ff191683800117855562000194565b8280016001018555821562000194579182015b828111156200019457825182559160200191906001019062000177565b50620001a2929150620001a6565b5090565b620001c391905b80821115620001a25760008155600101620001ad565b90565b6118ae80620001d66000396000f30060806040526004361061015e5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde03811461016d578063095ea7b3146101f757806317ffc3201461022f57806318160ddd1461025257806323b872dd146102795780632aed7f3f146102a35780633018205f146102c4578063313ce567146102f55780633823caec1461030a5780634000aea01461033d578063449a52f81461036e5780634e71e0c8146103925780636eb4c609146103a757806370a08231146103dd578063715018a6146103fe57806383197ef0146104135780638ba47bdd146104285780638da5cb5b1461047257806392eefe9b1461048757806395d89b41146104a85780639f727c27146104bd578063a9059cbb146104d2578063c0ee0b8a146104f6578063dd62ed3e14610527578063e30c39781461054e578063f2fde38b14610563578063f5074f4114610584575b34801561016a57600080fd5b50005b34801561017957600080fd5b506101826105a5565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101bc5781810151838201526020016101a4565b50505050905090810190601f1680156101e95780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561020357600080fd5b5061021b600160a060020a0360043516602435610633565b604080519115158252519081900360200190f35b34801561023b57600080fd5b50610250600160a060020a0360043516610721565b005b34801561025e57600080fd5b506102676107ed565b60408051918252519081900360200190f35b34801561028557600080fd5b5061021b600160a060020a036004358116906024351660443561087d565b3480156102af57600080fd5b50610250600160a060020a0360043516610977565b3480156102d057600080fd5b506102d9610a11565b60408051600160a060020a039092168252519081900360200190f35b34801561030157600080fd5b50610267610a20565b34801561031657600080fd5b5061021b600160a060020a036004351660243560443560ff6064351660843560a435610a7f565b34801561034957600080fd5b5061021b60048035600160a060020a0316906024803591604435918201910135610b90565b34801561037a57600080fd5b5061021b600160a060020a0360043516602435610d15565b34801561039e57600080fd5b50610250610e04565b3480156103b357600080fd5b50610267600160a060020a036004358116906024351660443560ff6064351660843560a435610e8c565b3480156103e957600080fd5b50610267600160a060020a0360043516610fa0565b34801561040a57600080fd5b5061025061103d565b34801561041f57600080fd5b506102506110a9565b34801561043457600080fd5b5061043d6110ce565b604080517fffffff00000000000000000000000000000000000000000000000000000000009092168252519081900360200190f35b34801561047e57600080fd5b506102d96110f4565b34801561049357600080fd5b50610250600160a060020a0360043516611103565b3480156104b457600080fd5b5061018261150c565b3480156104c957600080fd5b50610250611567565b3480156104de57600080fd5b5061021b600160a060020a03600435166024356115b9565b34801561050257600080fd5b5061025060048035600160a060020a03169060248035916044359182019101356116a7565b34801561053357600080fd5b50610267600160a060020a03600435811690602435166116ac565b34801561055a57600080fd5b506102d9611752565b34801561056f57600080fd5b50610250600160a060020a0360043516611761565b34801561059057600080fd5b50610250600160a060020a03600435166117a7565b6003805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561062b5780601f106106005761010080835404028352916020019161062b565b820191906000526020600020905b81548152906001019060200180831161060e57829003601f168201915b505050505081565b600254604080517f774d5409000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a038581166024830152604482018590529151600093929092169163774d54099160648082019260209290919082900301818787803b1580156106ab57600080fd5b505af11580156106bf573d6000803e3d6000fd5b505050506040513d60208110156106d557600080fd5b5051604080518481529051919250600160a060020a0385169133917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925919081900360200190a392915050565b60008054600160a060020a0316331461073957600080fd5b604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051600160a060020a038416916370a082319160248083019260209291908290030181600087803b15801561079a57600080fd5b505af11580156107ae573d6000803e3d6000fd5b505050506040513d60208110156107c457600080fd5b50516000549091506107e990600160a060020a0384811691168363ffffffff6117ca16565b5050565b600254604080517f18160ddd0000000000000000000000000000000000000000000000000000000081529051600092600160a060020a0316916318160ddd91600480830192602092919082900301818787803b15801561084c57600080fd5b505af1158015610860573d6000803e3d6000fd5b505050506040513d602081101561087657600080fd5b5051905090565b600254604080517fe974fee9000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a0386811660248301528581166044830152606482018590529151600093929092169163e974fee99160848082019260209290919082900301818787803b1580156108fd57600080fd5b505af1158015610911573d6000803e3d6000fd5b505050506040513d602081101561092757600080fd5b5051604080518481529051919250600160a060020a0380861692908716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef919081900360200190a39392505050565b60008054600160a060020a0316331461098f57600080fd5b5060008054604080517ff2fde38b000000000000000000000000000000000000000000000000000000008152600160a060020a039283166004820152905184939284169263f2fde38b926024808201939182900301818387803b1580156109f557600080fd5b505af1158015610a09573d6000803e3d6000fd5b505050505050565b600254600160a060020a031690565b600254604080517f313ce5670000000000000000000000000000000000000000000000000000000081529051600092600160a060020a03169163313ce56791600480830192602092919082900301818787803b15801561084c57600080fd5b600254604080517f4eb00754000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a038981166024830152604482018990526064820188905260ff8716608483015260a4820186905260c4820185905291516000939290921691634eb007549160e48082019260209290919082900301818787803b158015610b1557600080fd5b505af1158015610b29573d6000803e3d6000fd5b505050506040513d6020811015610b3f57600080fd5b5051604080518881529051919250600091600160a060020a038a16917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef919081900360200190a39695505050505050565b6002546040517f9e7f43ca0000000000000000000000000000000000000000000000000000000081523360048201818152600160a060020a03888116602485015260448401889052608060648501908152608485018790526000959190911693639e7f43ca93928a928a928a928a92909160a40184848082843782019150509650505050505050602060405180830381600087803b158015610c3157600080fd5b505af1158015610c45573d6000803e3d6000fd5b505050506040513d6020811015610c5b57600080fd5b5051604080518681529051919250600160a060020a0387169133917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef919081900360200190a384600160a060020a031633600160a060020a03167fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c16868686604051808481526020018060200182810382528484828181526020019250808284376040519201829003965090945050505050a3949350505050565b600254604080517f322ec0fb000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a038581166024830152604482018590529151600093929092169163322ec0fb9160648082019260209290919082900301818787803b158015610d8d57600080fd5b505af1158015610da1573d6000803e3d6000fd5b505050506040513d6020811015610db757600080fd5b5051604080518481529051919250600160a060020a038516916000917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef919081900360200190a392915050565b600154600160a060020a03163314610e1b57600080fd5b60015460008054604051600160a060020a0393841693909116917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600180546000805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a03841617909155169055565b600254604080517f3cd1570f000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a03898116602483015288811660448301526064820188905260ff8716608483015260a4820186905260c4820185905291516000939290921691633cd1570f9160e48082019260209290919082900301818787803b158015610f2357600080fd5b505af1158015610f37573d6000803e3d6000fd5b505050506040513d6020811015610f4d57600080fd5b5051604080518281529051919250600160a060020a0380891692908a16917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef919081900360200190a39695505050505050565b600254604080517f70a08231000000000000000000000000000000000000000000000000000000008152600160a060020a038481166004830152915160009392909216916370a082319160248082019260209290919082900301818787803b15801561100b57600080fd5b505af115801561101f573d6000803e3d6000fd5b505050506040513d602081101561103557600080fd5b505192915050565b600054600160a060020a0316331461105457600080fd5b60008054604051600160a060020a03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a26000805473ffffffffffffffffffffffffffffffffffffffff19169055565b600054600160a060020a031633146110c057600080fd5b600054600160a060020a0316ff5b6005547d0100000000000000000000000000000000000000000000000000000000000281565b600054600160a060020a031681565b600054600160a060020a0316331461111a57600080fd5b600160a060020a03811615156111b757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f636f6e74726f6c6c657220616464726573732063616e6e6f742062652074686560448201527f206e756c6c206164647265737300000000000000000000000000000000000000606482015290519081900360840190fd5b600254600554604051600160a060020a038481169316917d010000000000000000000000000000000000000000000000000000000000027fffffff000000000000000000000000000000000000000000000000000000000016907f2ce3a3a1c097de2b147145a1e6f236b569e75e7310e3b0b436d5dea8f60e35dc90600090a46002805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a038381169190911791829055604080517e3074ff0000000000000000000000000000000000000000000000000000000081529051309390921691623074ff916004808201926020929091908290030181600087803b1580156112ba57600080fd5b505af11580156112ce573d6000803e3d6000fd5b505050506040513d60208110156112e457600080fd5b5051600160a060020a03161461138157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f636f6e74726f6c6c65722066726f6e74656e6420646f6573206e6f7420706f6960448201527f6e74206261636b00000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600554600254604080517f8ba47bdd00000000000000000000000000000000000000000000000000000000815290517d0100000000000000000000000000000000000000000000000000000000009093027fffffff00000000000000000000000000000000000000000000000000000000001692600160a060020a0390921691638ba47bdd916004808201926020929091908290030181600087803b15801561142957600080fd5b505af115801561143d573d6000803e3d6000fd5b505050506040513d602081101561145357600080fd5b50517fffffff0000000000000000000000000000000000000000000000000000000000161461150957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f7469636b657220646f6573206e6f74206d6174636820636f6e74726f6c6c657260448201527f207469636b657400000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b50565b6004805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561062b5780601f106106005761010080835404028352916020019161062b565b600054600160a060020a0316331461157e57600080fd5b60008054604051600160a060020a0390911691303180156108fc02929091818181858888f19350505050158015611509573d6000803e3d6000fd5b600254604080517fe174fd94000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a038581166024830152604482018590529151600093929092169163e174fd949160648082019260209290919082900301818787803b15801561163157600080fd5b505af1158015611645573d6000803e3d6000fd5b505050506040513d602081101561165b57600080fd5b5051604080518481529051919250600160a060020a0385169133917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef919081900360200190a392915050565b600080fd5b600254604080517fdd62ed3e000000000000000000000000000000000000000000000000000000008152600160a060020a03858116600483015284811660248301529151600093929092169163dd62ed3e9160448082019260209290919082900301818787803b15801561171f57600080fd5b505af1158015611733573d6000803e3d6000fd5b505050506040513d602081101561174957600080fd5b50519392505050565b600154600160a060020a031681565b600054600160a060020a0316331461177857600080fd5b6001805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b600054600160a060020a031633146117be57600080fd5b80600160a060020a0316ff5b82600160a060020a031663a9059cbb83836040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083600160a060020a0316600160a060020a0316815260200182815260200192505050602060405180830381600087803b15801561184657600080fd5b505af115801561185a573d6000803e3d6000fd5b505050506040513d602081101561187057600080fd5b5051151561187d57600080fd5b5050505600a165627a7a72305820765e12d38c92f02cf10981887c9c07e0c5dcbc669c7b320acc5a00ab94b339f90029
Deployed Bytecode
0x60806040526004361061015e5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde03811461016d578063095ea7b3146101f757806317ffc3201461022f57806318160ddd1461025257806323b872dd146102795780632aed7f3f146102a35780633018205f146102c4578063313ce567146102f55780633823caec1461030a5780634000aea01461033d578063449a52f81461036e5780634e71e0c8146103925780636eb4c609146103a757806370a08231146103dd578063715018a6146103fe57806383197ef0146104135780638ba47bdd146104285780638da5cb5b1461047257806392eefe9b1461048757806395d89b41146104a85780639f727c27146104bd578063a9059cbb146104d2578063c0ee0b8a146104f6578063dd62ed3e14610527578063e30c39781461054e578063f2fde38b14610563578063f5074f4114610584575b34801561016a57600080fd5b50005b34801561017957600080fd5b506101826105a5565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101bc5781810151838201526020016101a4565b50505050905090810190601f1680156101e95780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561020357600080fd5b5061021b600160a060020a0360043516602435610633565b604080519115158252519081900360200190f35b34801561023b57600080fd5b50610250600160a060020a0360043516610721565b005b34801561025e57600080fd5b506102676107ed565b60408051918252519081900360200190f35b34801561028557600080fd5b5061021b600160a060020a036004358116906024351660443561087d565b3480156102af57600080fd5b50610250600160a060020a0360043516610977565b3480156102d057600080fd5b506102d9610a11565b60408051600160a060020a039092168252519081900360200190f35b34801561030157600080fd5b50610267610a20565b34801561031657600080fd5b5061021b600160a060020a036004351660243560443560ff6064351660843560a435610a7f565b34801561034957600080fd5b5061021b60048035600160a060020a0316906024803591604435918201910135610b90565b34801561037a57600080fd5b5061021b600160a060020a0360043516602435610d15565b34801561039e57600080fd5b50610250610e04565b3480156103b357600080fd5b50610267600160a060020a036004358116906024351660443560ff6064351660843560a435610e8c565b3480156103e957600080fd5b50610267600160a060020a0360043516610fa0565b34801561040a57600080fd5b5061025061103d565b34801561041f57600080fd5b506102506110a9565b34801561043457600080fd5b5061043d6110ce565b604080517fffffff00000000000000000000000000000000000000000000000000000000009092168252519081900360200190f35b34801561047e57600080fd5b506102d96110f4565b34801561049357600080fd5b50610250600160a060020a0360043516611103565b3480156104b457600080fd5b5061018261150c565b3480156104c957600080fd5b50610250611567565b3480156104de57600080fd5b5061021b600160a060020a03600435166024356115b9565b34801561050257600080fd5b5061025060048035600160a060020a03169060248035916044359182019101356116a7565b34801561053357600080fd5b50610267600160a060020a03600435811690602435166116ac565b34801561055a57600080fd5b506102d9611752565b34801561056f57600080fd5b50610250600160a060020a0360043516611761565b34801561059057600080fd5b50610250600160a060020a03600435166117a7565b6003805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561062b5780601f106106005761010080835404028352916020019161062b565b820191906000526020600020905b81548152906001019060200180831161060e57829003601f168201915b505050505081565b600254604080517f774d5409000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a038581166024830152604482018590529151600093929092169163774d54099160648082019260209290919082900301818787803b1580156106ab57600080fd5b505af11580156106bf573d6000803e3d6000fd5b505050506040513d60208110156106d557600080fd5b5051604080518481529051919250600160a060020a0385169133917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925919081900360200190a392915050565b60008054600160a060020a0316331461073957600080fd5b604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051600160a060020a038416916370a082319160248083019260209291908290030181600087803b15801561079a57600080fd5b505af11580156107ae573d6000803e3d6000fd5b505050506040513d60208110156107c457600080fd5b50516000549091506107e990600160a060020a0384811691168363ffffffff6117ca16565b5050565b600254604080517f18160ddd0000000000000000000000000000000000000000000000000000000081529051600092600160a060020a0316916318160ddd91600480830192602092919082900301818787803b15801561084c57600080fd5b505af1158015610860573d6000803e3d6000fd5b505050506040513d602081101561087657600080fd5b5051905090565b600254604080517fe974fee9000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a0386811660248301528581166044830152606482018590529151600093929092169163e974fee99160848082019260209290919082900301818787803b1580156108fd57600080fd5b505af1158015610911573d6000803e3d6000fd5b505050506040513d602081101561092757600080fd5b5051604080518481529051919250600160a060020a0380861692908716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef919081900360200190a39392505050565b60008054600160a060020a0316331461098f57600080fd5b5060008054604080517ff2fde38b000000000000000000000000000000000000000000000000000000008152600160a060020a039283166004820152905184939284169263f2fde38b926024808201939182900301818387803b1580156109f557600080fd5b505af1158015610a09573d6000803e3d6000fd5b505050505050565b600254600160a060020a031690565b600254604080517f313ce5670000000000000000000000000000000000000000000000000000000081529051600092600160a060020a03169163313ce56791600480830192602092919082900301818787803b15801561084c57600080fd5b600254604080517f4eb00754000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a038981166024830152604482018990526064820188905260ff8716608483015260a4820186905260c4820185905291516000939290921691634eb007549160e48082019260209290919082900301818787803b158015610b1557600080fd5b505af1158015610b29573d6000803e3d6000fd5b505050506040513d6020811015610b3f57600080fd5b5051604080518881529051919250600091600160a060020a038a16917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef919081900360200190a39695505050505050565b6002546040517f9e7f43ca0000000000000000000000000000000000000000000000000000000081523360048201818152600160a060020a03888116602485015260448401889052608060648501908152608485018790526000959190911693639e7f43ca93928a928a928a928a92909160a40184848082843782019150509650505050505050602060405180830381600087803b158015610c3157600080fd5b505af1158015610c45573d6000803e3d6000fd5b505050506040513d6020811015610c5b57600080fd5b5051604080518681529051919250600160a060020a0387169133917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef919081900360200190a384600160a060020a031633600160a060020a03167fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c16868686604051808481526020018060200182810382528484828181526020019250808284376040519201829003965090945050505050a3949350505050565b600254604080517f322ec0fb000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a038581166024830152604482018590529151600093929092169163322ec0fb9160648082019260209290919082900301818787803b158015610d8d57600080fd5b505af1158015610da1573d6000803e3d6000fd5b505050506040513d6020811015610db757600080fd5b5051604080518481529051919250600160a060020a038516916000917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef919081900360200190a392915050565b600154600160a060020a03163314610e1b57600080fd5b60015460008054604051600160a060020a0393841693909116917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600180546000805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a03841617909155169055565b600254604080517f3cd1570f000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a03898116602483015288811660448301526064820188905260ff8716608483015260a4820186905260c4820185905291516000939290921691633cd1570f9160e48082019260209290919082900301818787803b158015610f2357600080fd5b505af1158015610f37573d6000803e3d6000fd5b505050506040513d6020811015610f4d57600080fd5b5051604080518281529051919250600160a060020a0380891692908a16917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef919081900360200190a39695505050505050565b600254604080517f70a08231000000000000000000000000000000000000000000000000000000008152600160a060020a038481166004830152915160009392909216916370a082319160248082019260209290919082900301818787803b15801561100b57600080fd5b505af115801561101f573d6000803e3d6000fd5b505050506040513d602081101561103557600080fd5b505192915050565b600054600160a060020a0316331461105457600080fd5b60008054604051600160a060020a03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a26000805473ffffffffffffffffffffffffffffffffffffffff19169055565b600054600160a060020a031633146110c057600080fd5b600054600160a060020a0316ff5b6005547d0100000000000000000000000000000000000000000000000000000000000281565b600054600160a060020a031681565b600054600160a060020a0316331461111a57600080fd5b600160a060020a03811615156111b757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f636f6e74726f6c6c657220616464726573732063616e6e6f742062652074686560448201527f206e756c6c206164647265737300000000000000000000000000000000000000606482015290519081900360840190fd5b600254600554604051600160a060020a038481169316917d010000000000000000000000000000000000000000000000000000000000027fffffff000000000000000000000000000000000000000000000000000000000016907f2ce3a3a1c097de2b147145a1e6f236b569e75e7310e3b0b436d5dea8f60e35dc90600090a46002805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a038381169190911791829055604080517e3074ff0000000000000000000000000000000000000000000000000000000081529051309390921691623074ff916004808201926020929091908290030181600087803b1580156112ba57600080fd5b505af11580156112ce573d6000803e3d6000fd5b505050506040513d60208110156112e457600080fd5b5051600160a060020a03161461138157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f636f6e74726f6c6c65722066726f6e74656e6420646f6573206e6f7420706f6960448201527f6e74206261636b00000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600554600254604080517f8ba47bdd00000000000000000000000000000000000000000000000000000000815290517d0100000000000000000000000000000000000000000000000000000000009093027fffffff00000000000000000000000000000000000000000000000000000000001692600160a060020a0390921691638ba47bdd916004808201926020929091908290030181600087803b15801561142957600080fd5b505af115801561143d573d6000803e3d6000fd5b505050506040513d602081101561145357600080fd5b50517fffffff0000000000000000000000000000000000000000000000000000000000161461150957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f7469636b657220646f6573206e6f74206d6174636820636f6e74726f6c6c657260448201527f207469636b657400000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b50565b6004805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561062b5780601f106106005761010080835404028352916020019161062b565b600054600160a060020a0316331461157e57600080fd5b60008054604051600160a060020a0390911691303180156108fc02929091818181858888f19350505050158015611509573d6000803e3d6000fd5b600254604080517fe174fd94000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a038581166024830152604482018590529151600093929092169163e174fd949160648082019260209290919082900301818787803b15801561163157600080fd5b505af1158015611645573d6000803e3d6000fd5b505050506040513d602081101561165b57600080fd5b5051604080518481529051919250600160a060020a0385169133917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef919081900360200190a392915050565b600080fd5b600254604080517fdd62ed3e000000000000000000000000000000000000000000000000000000008152600160a060020a03858116600483015284811660248301529151600093929092169163dd62ed3e9160448082019260209290919082900301818787803b15801561171f57600080fd5b505af1158015611733573d6000803e3d6000fd5b505050506040513d602081101561174957600080fd5b50519392505050565b600154600160a060020a031681565b600054600160a060020a0316331461177857600080fd5b6001805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b600054600160a060020a031633146117be57600080fd5b80600160a060020a0316ff5b82600160a060020a031663a9059cbb83836040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083600160a060020a0316600160a060020a0316815260200182815260200192505050602060405180830381600087803b15801561184657600080fd5b505af115801561185a573d6000803e3d6000fd5b505050506040513d602081101561187057600080fd5b5051151561187d57600080fd5b5050505600a165627a7a72305820765e12d38c92f02cf10981887c9c07e0c5dcbc669c7b320acc5a00ab94b339f90029
Deployed Bytecode Sourcemap
69681:143:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;69681:143:0;;61117:18;;8:9:-1;5:2;;;30:1;27;20:12;5:2;61117:18:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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;61117:18:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64803:209;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;64803:209:0;-1:-1:-1;;;;;64803:209:0;;;;;;;;;;;;;;;;;;;;;;;;;5494:155;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;5494:155:0;-1:-1:-1;;;;;5494:155:0;;;;;;;68006:102;;8:9:-1;5:2;;;30:1;27;20:12;5:2;68006:102:0;;;;;;;;;;;;;;;;;;;;64137:218;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;64137:218:0;-1:-1:-1;;;;;64137:218:0;;;;;;;;;;;;8450:169;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;8450:169:0;-1:-1:-1;;;;;8450:169:0;;;;;67805:102;;8:9:-1;5:2;;;30:1;27;20:12;5:2;67805:102:0;;;;;;;;-1:-1:-1;;;;;67805:102:0;;;;;;;;;;;;;;68902:96;;8:9:-1;5:2;;;30:1;27;20:12;5:2;68902:96:0;;;;66449:272;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;66449:272:0;-1:-1:-1;;;;;66449:272:0;;;;;;;;;;;;;;;;;65391:308;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;65391:308:0;;;;-1:-1:-1;;;;;65391:308:0;;;;;;;;;;;;;;;;65852:208;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;65852:208:0;-1:-1:-1;;;;;65852:208:0;;;;;;;2673:168;;8:9:-1;5:2;;;30:1;27;20:12;5:2;2673:168:0;;;;67422:272;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;67422:272:0;-1:-1:-1;;;;;67422:272:0;;;;;;;;;;;;;;;;;;;;68275:112;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;68275:112:0;-1:-1:-1;;;;;68275:112:0;;;;;1108:114;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1108:114:0;;;;9453:68;;8:9:-1;5:2;;;30:1;27;20:12;5:2;9453:68:0;;;;61169:20;;8:9:-1;5:2;;;30:1;27;20:12;5:2;61169:20:0;;;;;;;;;;;;;;;;;;;;;;;313;;8:9:-1;5:2;;;30:1;27;20:12;5:2;313:20:0;;;;63037:453;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;63037:453:0;-1:-1:-1;;;;;63037:453:0;;;;;61142:20;;8:9:-1;5:2;;;30:1;27;20:12;5:2;61142:20:0;;;;6928:93;;8:9:-1;5:2;;;30:1;27;20:12;5:2;6928:93:0;;;;63644:196;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;63644:196:0;-1:-1:-1;;;;;63644:196:0;;;;;;;7722:172;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;7722:172:0;;;;-1:-1:-1;;;;;7722:172:0;;;;;;;;;;;;;;;;68640:142;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;68640:142:0;-1:-1:-1;;;;;68640:142:0;;;;;;;;;;2124:27;;8:9:-1;5:2;;;30:1;27;20:12;5:2;2124:27:0;;;;2486:98;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;2486:98:0;-1:-1:-1;;;;;2486:98:0;;;;;9527;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;9527:98:0;-1:-1:-1;;;;;9527:98:0;;;;;61117:18;;;;;;;;;;;;;;;-1:-1:-1;;61117:18:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;64803:209::-;64893:10;;:58;;;;;;64923:10;64893:58;;;;-1:-1:-1;;;;;64893:58:0;;;;;;;;;;;;;;;64868:7;;64893:10;;;;;:29;;:58;;;;;;;;;;;;;;;64868:7;64893:10;:58;;;5:2:-1;;;;30:1;27;20:12;5:2;64893:58:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;64893:58:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;64893:58:0;64967:37;;;;;;;;64893:58;;-1:-1:-1;;;;;;64967:37:0;;;64976:10;;64967:37;;;;;;64893:58;64967:37;;;64803:209;;;;:::o;5494:155::-;5561:15;816:5;;-1:-1:-1;;;;;816:5:0;802:10;:19;794:28;;;;;;5579:22;;;;;;5596:4;5579:22;;;;;;-1:-1:-1;;;;;5579:16:0;;;;;:22;;;;;;;;;;;;;;-1:-1:-1;5579:16:0;:22;;;5:2:-1;;;;30:1;27;20:12;5:2;5579:22:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;5579:22:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;5579:22:0;5628:5;;5579:22;;-1:-1:-1;5608:35:0;;-1:-1:-1;;;;;5608:19:0;;;;5628:5;5579:22;5608:35;:19;:35;:::i;:::-;5494:155;;:::o;68006:102::-;68076:10;;:24;;;;;;;;68052:4;;-1:-1:-1;;;;;68076:10:0;;:22;;:24;;;;;;;;;;;;;;68052:4;68076:10;:24;;;5:2:-1;;;;30:1;27;20:12;5:2;68076:24:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;68076:24:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;68076:24:0;;-1:-1:-1;68006:102:0;:::o;64137:218::-;64241:10;;:64;;;;;;64276:10;64241:64;;;;-1:-1:-1;;;;;64241:64:0;;;;;;;;;;;;;;;;;;;;;;64216:7;;64241:10;;;;;:34;;:64;;;;;;;;;;;;;;;64216:7;64241:10;:64;;;5:2:-1;;;;30:1;27;20:12;5:2;64241:64:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;64241:64:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;64241:64:0;64321:26;;;;;;;;64241:64;;-1:-1:-1;;;;;;64321:26:0;;;;;;;;;;;;;;64241:64;64321:26;;;64137:218;;;;;:::o;8450:169::-;8524:20;816:5;;-1:-1:-1;;;;;816:5:0;802:10;:19;794:28;;;;;;-1:-1:-1;8607:5:0;;;8576:37;;;;;;-1:-1:-1;;;;;8607:5:0;;;8576:37;;;;;;8555:13;;8576:30;;;;;;:37;;;;;;;;;;;8607:5;8576:30;:37;;;5:2:-1;;;;30:1;27;20:12;5:2;8576:37:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;8576:37:0;;;;8450:169;;:::o;67805:102::-;67888:10;;-1:-1:-1;;;;;67888:10:0;67805:102;:::o;68902:96::-;68969:10;;:21;;;;;;;;68945:4;;-1:-1:-1;;;;;68969:10:0;;:19;;:21;;;;;;;;;;;;;;68945:4;68969:10;:21;;;5:2:-1;;;;30:1;27;20:12;66449:272:0;66602:10;;:68;;;;;;66633:10;66602:68;;;;-1:-1:-1;;;;;66602:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66572:7;;66602:10;;;;;:30;;:68;;;;;;;;;;;;;;;66572:7;66602:10;:68;;;5:2:-1;;;;30:1;27;20:12;5:2;66602:68:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;66602:68:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;66602:68:0;66686:27;;;;;;;;66602:68;;-1:-1:-1;66701:3:0;;-1:-1:-1;;;;;66686:27:0;;;;;;;;;66602:68;66686:27;;;66449:272;;;;;;;;:::o;65391:308::-;65522:10;;:67;;;;;65560:10;65522:67;;;;;;-1:-1:-1;;;;;65522:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;65492:7;;65522:10;;;;;:37;;65560:10;65572:2;;65576:6;;65584:4;;;;65522:67;;;;65584:4;;;;65522:67;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;65522:67:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;65522:67:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;65522:67:0;65605:32;;;;;;;;65522:67;;-1:-1:-1;;;;;;65605:32:0;;;65614:10;;65605:32;;;;;;65522:67;65605:32;;;65674:2;-1:-1:-1;;;;;65653:38:0;65662:10;-1:-1:-1;;;;;65653:38:0;;65678:6;65686:4;;65653:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;65653:38:0;;-1:-1:-1;;;;;65653:38:0;65391:308;;;;;;:::o;65852:208::-;65959:10;;:52;;;;;;65988:10;65959:52;;;;-1:-1:-1;;;;;65959:52:0;;;;;;;;;;;;;;;65929:7;;65959:10;;;;;:28;;:52;;;;;;;;;;;;;;;65929:7;65959:10;:52;;;5:2:-1;;;;30:1;27;20:12;5:2;65959:52:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;65959:52:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;65959:52:0;66027:25;;;;;;;;65959:52;;-1:-1:-1;;;;;;66027:25:0;;;66036:3;;66027:25;;;;;;65959:52;66027:25;;;65852:208;;;;:::o;2673:168::-;2310:12;;-1:-1:-1;;;;;2310:12:0;2296:10;:26;2288:35;;;;;;2763:12;;;2756:5;;2735:41;;-1:-1:-1;;;;;2763:12:0;;;;2756:5;;;;2735:41;;;2791:12;;;;2783:20;;-1:-1:-1;;2783:20:0;;;-1:-1:-1;;;;;2791:12:0;;2783:20;;;;2810:25;;;2673:168::o;67422:272::-;67581:10;;:63;;;;;;67611:10;67581:63;;;;-1:-1:-1;;;;;67581:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67543:11;;67581:10;;;;;:29;;:63;;;;;;;;;;;;;;;67543:11;67581:10;:63;;;5:2:-1;;;;30:1;27;20:12;5:2;67581:63:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;67581:63:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;67581:63:0;67660:26;;;;;;;;67581:63;;-1:-1:-1;;;;;;67660:26:0;;;;;;;;;;;;;;67581:63;67660:26;;;67422:272;;;;;;;;:::o;68275:112::-;68354:10;;:25;;;;;;-1:-1:-1;;;;;68354:25:0;;;;;;;;;68330:4;;68354:10;;;;;:20;;:25;;;;;;;;;;;;;;;68330:4;68354:10;:25;;;5:2:-1;;;;30:1;27;20:12;5:2;68354:25:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;68354:25:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;68354:25:0;;68275:112;-1:-1:-1;;68275:112:0:o;1108:114::-;816:5;;-1:-1:-1;;;;;816:5:0;802:10;:19;794:28;;;;;;1185:5;;;1166:25;;-1:-1:-1;;;;;1185:5:0;;;;1166:25;;;1214:1;1198:18;;-1:-1:-1;;1198:18:0;;;1108:114::o;9453:68::-;816:5;;-1:-1:-1;;;;;816:5:0;802:10;:19;794:28;;;;;;9509:5;;-1:-1:-1;;;;;9509:5:0;9496:19;61169:20;;;;;;:::o;313:::-;;;-1:-1:-1;;;;;313:20:0;;:::o;63037:453::-;816:5;;-1:-1:-1;;;;;816:5:0;802:10;:19;794:28;;;;;;-1:-1:-1;;;;;63116:15:0;;;;63108:73;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63216:10;;63208:6;;63197:40;;-1:-1:-1;;;;;63197:40:0;;;;63216:10;;63208:6;;63197:40;;;;;63216:10;;63197:40;63248:10;:38;;-1:-1:-1;;63248:38:0;-1:-1:-1;;;;;63248:38:0;;;;;;;;;;;63305:24;;;;;;;;63341:4;;63305:10;;;;:22;;:24;;;;;;;;;;;;;;;-1:-1:-1;63305:10:0;:24;;;5:2:-1;;;;30:1;27;20:12;5:2;63305:24:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;63305:24:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;63305:24:0;-1:-1:-1;;;;;63305:41:0;;63297:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63432:6;;63409:10;;:19;;;;;;;;63432:6;;;;63409:29;;;-1:-1:-1;;;;;63409:10:0;;;;:17;;:19;;;;;;;;;;;;;;;63432:6;63409:10;:19;;;5:2:-1;;;;30:1;27;20:12;5:2;63409:19:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;63409:19:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;63409:19:0;:29;;;63401:81;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63037:453;:::o;61142:20::-;;;;;;;;;;;;;;;-1:-1:-1;;61142:20:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6928:93;816:5;;-1:-1:-1;;;;;816:5:0;802:10;:19;794:28;;;;;;6978:5;;;:37;;-1:-1:-1;;;;;6978:5:0;;;;7001:4;6993:21;6978:37;;;;;6993:21;;6978:37;:5;:37;6993:21;6978:5;:37;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;63644:196:0;63730:10;;:54;;;;;;63761:10;63730:54;;;;-1:-1:-1;;;;;63730:54:0;;;;;;;;;;;;;;;63705:7;;63730:10;;;;;:30;;:54;;;;;;;;;;;;;;;63705:7;63730:10;:54;;;5:2:-1;;;;30:1;27;20:12;5:2;63730:54:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;63730:54:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;63730:54:0;63800:32;;;;;;;;63730:54;;-1:-1:-1;;;;;;63800:32:0;;;63809:10;;63800:32;;;;;;63730:54;63800:32;;;63644:196;;;;:::o;7722:172::-;7880:8;;;68640:142;68738:10;;:36;;;;;;-1:-1:-1;;;;;68738:36:0;;;;;;;;;;;;;;;;68714:4;;68738:10;;;;;:20;;:36;;;;;;;;;;;;;;;68714:4;68738:10;:36;;;5:2:-1;;;;30:1;27;20:12;5:2;68738:36:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;68738:36:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;68738:36:0;;68640:142;-1:-1:-1;;;68640:142:0:o;2124:27::-;;;-1:-1:-1;;;;;2124:27:0;;:::o;2486:98::-;816:5;;-1:-1:-1;;;;;816:5:0;802:10;:19;794:28;;;;;;2555:12;:23;;-1:-1:-1;;2555:23:0;-1:-1:-1;;;;;2555:23:0;;;;;;;;;;2486:98::o;9527:::-;816:5;;-1:-1:-1;;;;;816:5:0;802:10;:19;794:28;;;;;;9608:10;-1:-1:-1;;;;;9595:24:0;;4380:157;4502:6;-1:-1:-1;;;;;4502:15:0;;4518:3;4523:6;4502:28;;;;;;;;;;;;;-1:-1:-1;;;;;4502:28:0;-1:-1:-1;;;;;4502:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;4502:28:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;4502:28:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;4502:28:0;4494:37;;;;;;;;4380:157;;;:::o
Swarm Source
bzzr://765e12d38c92f02cf10981887c9c07e0c5dcbc669c7b320acc5a00ab94b339f9
Loading...
Loading
Loading...
Loading
OVERVIEW
The euro e-money token by Monerium EMI, a regulated entity, licensed in the EEA. E-money is recognised as a digital alternative to cash, 1:1 backed in high-quality liquid assets and is unconditionally redeemable on demand.Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.