Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 11806879 | 1185 days ago | IN | Create: TrueFi | 0 ETH | 0.2561283 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
TrueFi
Compiler Version
v0.6.10+commit.00c0fcaf
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-02-07 */ /** *Submitted for verification at Etherscan.io on 2020-11-12 */ // &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& // &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& // &&&&&&&&&&&&&&&&&&&&&&&&&&&&&%&&&&%%%%&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& // &&&&&&&&&&&&&&&&&&&&&&&&%(, .*#&&&&&&&&&&&&&&&&&&&&&&& // &&&&&&&&&&&&&&&&&&&&#. ,/#%%%%%%%#(/, *%&&&&&&&&&&&&&&&&&& // &&&&&&&&&&&&&&&&&( /&&&&&&&&&&&&&&&&&&&&&%&%* ,%&&&&&&&&&&&&&&& // &&&&&&&&&&&&&&%, *%&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&%, (&&&&&&&&&&&&& // &&&&&&&&&&&&&, #&&# ./#&&&&&&&&%, %&&&&&&&&&&& // &&&&&&&&&&&# (&&&&# ,%&&&&&&*/&&&&&&&&&& // &&&&&&&&&&( %&&&&&# /&&&&&&&&&&&&&&&&&&%#, .%&&&&&(%&&&&&&&& // &&&&&&&&&% #&&&&&&# /&&&&&&&&&&&&&&&&&&&&&&&( .%&&&&&&&&&&&&& // &&&&&&&&&/ ,&&&&&&&# /&&&&&&&&&&&&&&&&%%%%&&&&%% /&&&&&&&&&&&& // &&&&&&&&&* /&&&&&&&# %&&&&&&, (&&&&&&&* /&&&&&&&&&&& // &&&&&&&&&/ *&&&&&&&%////////* %&&&&&&, (&&&&&&&&, #&&&&&&&&&& // &&&&&&&&&# &&&&&&&&&&&&&&&&%. %&&&&&&. #&&&&&&&&# *&&&&&&&&&& // &&&&&&&&&&* ,&&%&&&&&&&&&&&&%. %&&&&&( .%&&&&&&&&# *&&&&&&&&&& // &&&&&&&&&&&, .&&&&&&&&&&&&&&%. /&&&&&# #&&&&&&&&&* (&&&&&&&&&& // &&&&&&&&&&&&# ,&&&&&&&&&&&&%.,%&&&&%, %&&&&&&&&&# .%&&&&&&&&&& // &&&&&&&&&&&&&&( ,#&&&&&&&&&&&&&&( (&&&&&&&&&&/ .%&&&&&&&&&&& // &&&&&&&&&&&&&&&&&* .. ,%&&&&&&&&&&# *&&&&&&&&&&&&& // &&&&&&&&&&&&&&&&&&&&%(. ./%&&&&&&&&&&&%* *&&&&&&&&&&&&&&& // &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&%(. .#&&&&&&&&&&&&&&&&& // &&&&&&&&&&&&&&&&&&&&&%/(%&&&&&&&&&&&&%#/. *%&&&&&&&&&&&&&&&&&&&& // &&&&&&&&&&&&&&&&&&&&&&&&&&%(, ,(%&&&&&&&&&&&&&&&&&&&&&&&&& // &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& // &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& // &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& // SPDX-License-Identifier: MIT pragma solidity ^0.6.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } pragma solidity ^0.6.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ 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. * * IMPORTANT: 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); } pragma solidity 0.6.10; interface RegistryClone { function syncAttributeValue( address _who, bytes32 _attribute, uint256 _value ) external; } contract Registry { struct AttributeData { uint256 value; bytes32 notes; address adminAddr; uint256 timestamp; } // never remove any storage variables address public owner; address public pendingOwner; bool initialized; // Stores arbitrary attributes for users. An example use case is an IERC20 // token that requires its users to go through a KYC/AML check - in this case // a validator can set an account's "hasPassedKYC/AML" attribute to 1 to indicate // that account can use the token. This mapping stores that value (1, in the // example) as well as which validator last set the value and at what time, // so that e.g. the check can be renewed at appropriate intervals. mapping(address => mapping(bytes32 => AttributeData)) attributes; // The logic governing who is allowed to set what attributes is abstracted as // this accessManager, so that it may be replaced by the owner as needed bytes32 constant WRITE_PERMISSION = keccak256("canWriteTo-"); mapping(bytes32 => RegistryClone[]) subscribers; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); event SetAttribute(address indexed who, bytes32 attribute, uint256 value, bytes32 notes, address indexed adminAddr); event SetManager(address indexed oldManager, address indexed newManager); event StartSubscription(bytes32 indexed attribute, RegistryClone indexed subscriber); event StopSubscription(bytes32 indexed attribute, RegistryClone indexed subscriber); // Allows a write if either a) the writer is that Registry's owner, or // b) the writer is writing to attribute foo and that writer already has // the canWriteTo-foo attribute set (in that same Registry) function confirmWrite(bytes32 _attribute, address _admin) internal view returns (bool) { return (_admin == owner || hasAttribute(_admin, keccak256(abi.encodePacked(WRITE_PERMISSION ^ _attribute)))); } // Writes are allowed only if the accessManager approves function setAttribute( address _who, bytes32 _attribute, uint256 _value, bytes32 _notes ) public { require(confirmWrite(_attribute, msg.sender)); attributes[_who][_attribute] = AttributeData(_value, _notes, msg.sender, block.timestamp); emit SetAttribute(_who, _attribute, _value, _notes, msg.sender); RegistryClone[] storage targets = subscribers[_attribute]; uint256 index = targets.length; while (index-- > 0) { targets[index].syncAttributeValue(_who, _attribute, _value); } } function subscribe(bytes32 _attribute, RegistryClone _syncer) external onlyOwner { subscribers[_attribute].push(_syncer); emit StartSubscription(_attribute, _syncer); } function unsubscribe(bytes32 _attribute, uint256 _index) external onlyOwner { uint256 length = subscribers[_attribute].length; require(_index < length); emit StopSubscription(_attribute, subscribers[_attribute][_index]); subscribers[_attribute][_index] = subscribers[_attribute][length - 1]; subscribers[_attribute].pop(); } function subscriberCount(bytes32 _attribute) public view returns (uint256) { return subscribers[_attribute].length; } function setAttributeValue( address _who, bytes32 _attribute, uint256 _value ) public { require(confirmWrite(_attribute, msg.sender)); attributes[_who][_attribute] = AttributeData(_value, "", msg.sender, block.timestamp); emit SetAttribute(_who, _attribute, _value, "", msg.sender); RegistryClone[] storage targets = subscribers[_attribute]; uint256 index = targets.length; while (index-- > 0) { targets[index].syncAttributeValue(_who, _attribute, _value); } } // Returns true if the uint256 value stored for this attribute is non-zero function hasAttribute(address _who, bytes32 _attribute) public view returns (bool) { return attributes[_who][_attribute].value != 0; } // Returns the exact value of the attribute, as well as its metadata function getAttribute(address _who, bytes32 _attribute) public view returns ( uint256, bytes32, address, uint256 ) { AttributeData memory data = attributes[_who][_attribute]; return (data.value, data.notes, data.adminAddr, data.timestamp); } function getAttributeValue(address _who, bytes32 _attribute) public view returns (uint256) { return attributes[_who][_attribute].value; } function getAttributeAdminAddr(address _who, bytes32 _attribute) public view returns (address) { return attributes[_who][_attribute].adminAddr; } function getAttributeTimestamp(address _who, bytes32 _attribute) public view returns (uint256) { return attributes[_who][_attribute].timestamp; } function syncAttribute( bytes32 _attribute, uint256 _startIndex, address[] calldata _addresses ) external { RegistryClone[] storage targets = subscribers[_attribute]; uint256 index = targets.length; while (index-- > _startIndex) { RegistryClone target = targets[index]; for (uint256 i = _addresses.length; i-- > 0; ) { address who = _addresses[i]; target.syncAttributeValue(who, _attribute, attributes[who][_attribute].value); } } } function reclaimEther(address payable _to) external onlyOwner { _to.transfer(address(this).balance); } function reclaimToken(IERC20 token, address _to) external onlyOwner { uint256 balance = token.balanceOf(address(this)); token.transfer(_to, balance); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(msg.sender == owner, "only Owner"); _; } /** * @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); } } pragma solidity 0.6.10; /** * All storage must be declared here * New storage must be appended to the end * Never remove items from this list */ contract ProxyStorage { bool initalized; uint256 public totalSupply; mapping(address => uint256) public balanceOf; mapping(address => mapping(address => uint256)) public allowance; mapping(uint144 => uint256) attributes; // see RegistrySubscriber address owner_; address pendingOwner_; /* Additionally, we have several keccak-based storage locations. * If you add more keccak-based storage mappings, such as mappings, you must document them here. * If the length of the keccak input is the same as an existing mapping, it is possible there could be a preimage collision. * A preimage collision can be used to attack the contract by treating one storage location as another, * which would always be a critical issue. * Carefully examine future keccak-based storage to ensure there can be no preimage collisions. ******************************************************************************************************* ** length input usage ******************************************************************************************************* ** 19 "trueXXX.proxy.owner" Proxy Owner ** 27 "trueXXX.pending.proxy.owner" Pending Proxy Owner ** 28 "trueXXX.proxy.implementation" Proxy Implementation ** 64 uint256(address),uint256(1) balanceOf ** 64 uint256(address),keccak256(uint256(address),uint256(2)) allowance ** 64 uint256(address),keccak256(bytes32,uint256(3)) attributes **/ } pragma solidity 0.6.10; /** * @title ClaimableContract * @dev The ClaimableContract contract is a copy of Claimable Contract by Zeppelin. and provides basic authorization control functions. Inherits storage layout of ProxyStorage. */ contract ClaimableContract is ProxyStorage { function owner() public view returns (address) { return owner_; } function pendingOwner() public view returns (address) { return pendingOwner_; } event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev sets the original `owner` of the contract to the sender * at construction. Must then be reinitialized */ constructor() public { owner_ = msg.sender; emit OwnershipTransferred(address(0), msg.sender); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(msg.sender == owner_, "only owner"); _; } /** * @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 { address _pendingOwner = pendingOwner_; emit OwnershipTransferred(owner_, _pendingOwner); owner_ = _pendingOwner; pendingOwner_ = address(0); } } pragma solidity ^0.6.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } } pragma solidity ^0.6.2; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // According to EIP-1052, 0x0 is the value returned for not-yet created accounts // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned // for accounts without code, i.e. `keccak256('')` bytes32 codehash; bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; // solhint-disable-next-line no-inline-assembly assembly { codehash := extcodehash(account) } return (codehash != accountHash && codehash != 0x0); } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return _functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); return _functionCallWithValue(target, data, value, errorMessage); } function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) { require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: weiValue }(data); if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File: contracts/trusttoken/common/ERC20.sol /** * @notice This is a copy of openzeppelin ERC20 contract with removed state variables. * Removing state variables has been necessary due to proxy pattern usage. * Changes to Openzeppelin ERC20 https://github.com/OpenZeppelin/openzeppelin-contracts/blob/de99bccbfd4ecd19d7369d01b070aa72c64423c9/contracts/token/ERC20/ERC20.sol: * - Remove state variables _name, _symbol, _decimals * - Use state variables balances, allowances, totalSupply from ProxyStorage * - Remove constructor * - Solidity version changed from ^0.6.0 to 0.6.10 * - Contract made abstract * - Remove inheritance from IERC20 because of ProxyStorage name conflicts * * See also: ClaimableOwnable.sol and ProxyStorage.sol */ pragma solidity 0.6.10; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin guidelines: functions revert instead * of returning `false` on failure. This behavior is nonetheless conventional * and does not conflict with the expectations of ERC20 applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ abstract contract ERC20 is ProxyStorage, Context { using SafeMath for uint256; using Address for address; /** * @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); /** * @dev Returns the name of the token. */ function name() public virtual pure returns (string memory); /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public virtual pure returns (string memory); /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5,05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is * called. * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public virtual pure returns (uint8) { return 18; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}; * * Requirements: * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom(address sender, address recipient, uint256 amount) public virtual returns (bool) { _transfer(sender, recipient, amount); _approve(sender, _msgSender(), allowance[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance")); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, allowance[_msgSender()][spender].add(addedValue)); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { _approve(_msgSender(), spender, allowance[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero")); return true; } /** * @dev Moves tokens `amount` from `sender` to `recipient`. * * This is internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer(address sender, address recipient, uint256 amount) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); balanceOf[sender] = balanceOf[sender].sub(amount, "ERC20: transfer amount exceeds balance"); balanceOf[recipient] = balanceOf[recipient].add(amount); emit Transfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements * * - `to` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); totalSupply = totalSupply.add(amount); balanceOf[account] = balanceOf[account].add(amount); emit Transfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); balanceOf[account] = balanceOf[account].sub(amount, "ERC20: burn amount exceeds balance"); totalSupply = totalSupply.sub(amount); emit Transfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens. * * This is internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve(address owner, address spender, uint256 amount) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); allowance[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be to transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ // solhint-disable-next-line no-empty-blocks function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { } } pragma solidity 0.6.10; /** * @title TimeLockedToken * @notice Time Locked ERC20 Token * @author Harold Hyatt * @dev Contract which gives the ability to time-lock tokens * * The registerLockup() function allows an account to transfer * its tokens to another account, locking them according to the * distribution epoch periods * * By overriding the balanceOf(), transfer(), and transferFrom() * functions in ERC20, an account can show its full, post-distribution * balance but only transfer or spend up to an allowed amount * * Every time an epoch passes, a portion of previously non-spendable tokens * are allowed to be transferred, and after all epochs have passed, the full * account balance is unlocked */ abstract contract TimeLockedToken is ERC20, ClaimableContract { using SafeMath for uint256; // represents total distribution for locked balances mapping(address => uint256) distribution; // start of the lockup period // Friday, July 24, 2020 4:58:31 PM GMT uint256 constant LOCK_START = 1595609911; // length of time to delay first epoch uint256 constant FIRST_EPOCH_DELAY = 30 days; // how long does an epoch last uint256 constant EPOCH_DURATION = 90 days; // number of epochs uint256 constant TOTAL_EPOCHS = 8; // registry of locked addresses address public timeLockRegistry; // allow unlocked transfers to special account bool public returnsLocked; modifier onlyTimeLockRegistry() { require(msg.sender == timeLockRegistry, "only TimeLockRegistry"); _; } /** * @dev Set TimeLockRegistry address * @param newTimeLockRegistry Address of TimeLockRegistry contract */ function setTimeLockRegistry(address newTimeLockRegistry) external onlyOwner { require(newTimeLockRegistry != address(0), "cannot be zero address"); require(newTimeLockRegistry != timeLockRegistry, "must be new TimeLockRegistry"); timeLockRegistry = newTimeLockRegistry; } /** * @dev Permanently lock transfers to return address * Lock returns so there isn't always a way to send locked tokens */ function lockReturns() external onlyOwner { returnsLocked = true; } /** * @dev Transfer function which includes unlocked tokens * Locked tokens can always be transfered back to the returns address * Transferring to owner allows re-issuance of funds through registry * * @param _from The address to send tokens from * @param _to The address that will receive the tokens * @param _value The amount of tokens to be transferred */ function _transfer( address _from, address _to, uint256 _value ) internal override { require(balanceOf[_from] >= _value, "insufficient balance"); // transfers to owner proceed as normal when returns allowed if (!returnsLocked && _to == owner_) { transferToOwner(_from, _value); return; } // check if enough unlocked balance to transfer require(unlockedBalance(_from) >= _value, "attempting to transfer locked funds"); super._transfer(_from, _to, _value); } /** * @dev Transfer tokens to owner. Used only when returns allowed. * @param _from The address to send tokens from * @param _value The amount of tokens to be transferred */ function transferToOwner(address _from, uint256 _value) internal { uint256 unlocked = unlockedBalance(_from); if (unlocked < _value) { // We want to have unlocked = value, i.e. // value = balance - distribution * epochsLeft / totalEpochs // distribution = (balance - value) * totalEpochs / epochsLeft distribution[_from] = balanceOf[_from].sub(_value).mul(TOTAL_EPOCHS).div(epochsLeft()); } super._transfer(_from, owner_, _value); } /** * @dev Check if amount we want to burn is unlocked before burning * @param _from The address whose tokens will burn * @param _value The amount of tokens to be burnt */ function _burn(address _from, uint256 _value) internal override { require(balanceOf[_from] >= _value, "insufficient balance"); require(unlockedBalance(_from) >= _value, "attempting to burn locked funds"); super._burn(_from, _value); } /** * @dev Transfer tokens to another account under the lockup schedule * Emits a transfer event showing a transfer to the recipient * Only the registry can call this function * @param receiver Address to receive the tokens * @param amount Tokens to be transferred */ function registerLockup(address receiver, uint256 amount) external onlyTimeLockRegistry { require(balanceOf[msg.sender] >= amount, "insufficient balance"); // add amount to locked distribution distribution[receiver] = distribution[receiver].add(amount); // transfer to recipient _transfer(msg.sender, receiver, amount); } /** * @dev Get locked balance for an account * @param account Account to check * @return Amount locked */ function lockedBalance(address account) public view returns (uint256) { // distribution * (epochsLeft / totalEpochs) return distribution[account].mul(epochsLeft()).div(TOTAL_EPOCHS); } /** * @dev Get unlocked balance for an account * @param account Account to check * @return Amount that is unlocked and available eg. to transfer */ function unlockedBalance(address account) public view returns (uint256) { // totalBalance - lockedBalance return balanceOf[account].sub(lockedBalance(account)); } /* * @dev Get number of epochs passed * @return Value between 0 and 8 of lockup epochs already passed */ function epochsPassed() public view returns (uint256) { // return 0 if timestamp is lower than start time if (block.timestamp < LOCK_START) { return 0; } // how long it has been since the beginning of lockup period uint256 timePassed = block.timestamp.sub(LOCK_START); // 1st epoch is FIRST_EPOCH_DELAY longer; we check to prevent subtraction underflow if (timePassed < FIRST_EPOCH_DELAY) { return 0; } // subtract the FIRST_EPOCH_DELAY, so that we can count all epochs as lasting EPOCH_DURATION uint256 totalEpochsPassed = timePassed.sub(FIRST_EPOCH_DELAY).div(EPOCH_DURATION); // epochs don't count over TOTAL_EPOCHS if (totalEpochsPassed > TOTAL_EPOCHS) { return TOTAL_EPOCHS; } return totalEpochsPassed; } function epochsLeft() public view returns (uint256) { return TOTAL_EPOCHS.sub(epochsPassed()); } /** * @dev Get timestamp of next epoch * Will revert if all epochs have passed * @return Timestamp of when the next epoch starts */ function nextEpoch() public view returns (uint256) { // get number of epochs passed uint256 passed = epochsPassed(); // if all epochs passed, return if (passed == TOTAL_EPOCHS) { // return INT_MAX return uint256(-1); } // if no epochs passed, return latest epoch + delay + standard duration if (passed == 0) { return latestEpoch().add(FIRST_EPOCH_DELAY).add(EPOCH_DURATION); } // otherwise return latest epoch + epoch duration return latestEpoch().add(EPOCH_DURATION); } /** * @dev Get timestamp of latest epoch * @return Timestamp of when the current epoch has started */ function latestEpoch() public view returns (uint256) { // get number of epochs passed uint256 passed = epochsPassed(); // if no epochs passed, return lock start time if (passed == 0) { return LOCK_START; } // accounts for first epoch being longer // lockStart + firstEpochDelay + (epochsPassed * epochDuration) return LOCK_START.add(FIRST_EPOCH_DELAY).add(passed.mul(EPOCH_DURATION)); } /** * @dev Get timestamp of final epoch * @return Timestamp of when the last epoch ends and all funds are released */ function finalEpoch() public pure returns (uint256) { // lockStart + firstEpochDelay + (epochDuration * totalEpochs) return LOCK_START.add(FIRST_EPOCH_DELAY).add(EPOCH_DURATION.mul(TOTAL_EPOCHS)); } /** * @dev Get timestamp of locking period start * @return Timestamp of locking period start */ function lockStart() public pure returns (uint256) { return LOCK_START; } } pragma solidity 0.6.10; /** * @title TrustToken * @dev The TrustToken contract is a claimable contract where the * owner can only mint or transfer ownership. TrustTokens use 8 decimals * in order to prevent rewards from getting stuck in the remainder on division. * Tolerates dilution to slash stake and accept rewards. */ contract TrueFi is TimeLockedToken { using SafeMath for uint256; uint256 constant MAX_SUPPLY = 145000000000000000; /** * @dev initialize trusttoken and give ownership to sender * This is necessary to set ownership for proxy */ function initialize() public { require(!initalized, "already initialized"); owner_ = msg.sender; initalized = true; } /** * @dev mint TRU * Can never mint more than MAX_SUPPLY = 1.45 billion */ function mint(address _to, uint256 _amount) external onlyOwner { if (totalSupply.add(_amount) <= MAX_SUPPLY) { _mint(_to, _amount); } else { revert("Max supply exceeded"); } } function burn(uint256 amount) external { _burn(msg.sender, amount); } function decimals() public override pure returns (uint8) { return 8; } function rounding() public pure returns (uint8) { return 8; } function name() public override pure returns (string memory) { return "TrueFi"; } function symbol() public override pure returns (string memory) { return "TRU"; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"epochsLeft","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"epochsPassed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"finalEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"latestEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockReturns","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lockStart","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"lockedBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"nextEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"registerLockup","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"returnsLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rounding","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"newTimeLockRegistry","type":"address"}],"name":"setTimeLockRegistry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"timeLockRegistry","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"unlockedBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50600580546001600160a01b031916339081179091556040516000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3611d91806100606000396000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c806370a082311161010f5780639c7e1a9e116100a2578063aea0e78b11610071578063aea0e78b146105cb578063dd62ed3e146105d3578063e30c39781461060e578063f2fde38b14610616576101f0565b80639c7e1a9e146105495780639cb118bf14610551578063a457c2d714610559578063a9059cbb14610592576101f0565b806395d89b41116100de57806395d89b41146104a2578063962399e2146104aa57806397671bea146104dd5780639ae697bf14610516576101f0565b806370a08231146104575780638129fc1c1461048a578063881ed6db146104925780638da5cb5b1461049a576101f0565b8063313ce5671161018757806340c10f191161015657806340c10f19146103c457806342966c68146103ff5780634e71e0c81461041c5780635e0fac2e14610424576101f0565b8063313ce56714610355578063335f57531461037b57806339509351146103835780633a98d88e146103bc576101f0565b8063238189a8116101c3578063238189a8146102e157806323b872dd146103125780632e440403146103555780632f38466214610373576101f0565b806306fdde03146101f5578063095ea7b31461027257806315cb7cfa146102bf57806318160ddd146102d9575b600080fd5b6101fd610649565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561023757818101518382015260200161021f565b50505050905090810190601f1680156102645780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102ab6004803603604081101561028857600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610681565b604080519115158252519081900360200190f35b6102c761069f565b60408051918252519081900360200190f35b6102c7610726565b6102e961072c565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6102ab6004803603606081101561032857600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135610748565b61035d6107ef565b6040805160ff9092168252519081900360200190f35b6102c76107f4565b6102ab610814565b6102ab6004803603604081101561039957600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610835565b6102c7610896565b6103fd600480360360408110156103da57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356108d2565b005b6103fd6004803603602081101561041557600080fd5b50356109c0565b6103fd6109cd565b6102c76004803603602081101561043a57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610a8b565b6102c76004803603602081101561046d57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610acb565b6103fd610add565b6102c7610b8c565b6102e9610b94565b6101fd610bb0565b6103fd600480360360208110156104c057600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610be7565b6103fd600480360360408110156104f357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610d72565b6102c76004803603602081101561052c57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610ea9565b6103fd610eed565b6102c7610f9a565b6102ab6004803603604081101561056f57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610fcf565b6102ab600480360360408110156105a857600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813516906020013561104a565b6102c761105e565b6102c7600480360360408110156105e957600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166110cf565b6102e96110ec565b6103fd6004803603602081101561062c57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611108565b60408051808201909152600681527f547275654669000000000000000000000000000000000000000000000000000060208201525b90565b600061069561068e6111bb565b84846111bf565b5060015b92915050565b6000635f1b13374210156106b55750600061067e565b60006106cb42635f1b133763ffffffff6112d216565b905062278d008110156106e257600091505061067e565b600061070a6276a7006106fe8462278d0063ffffffff6112d216565b9063ffffffff61131b16565b905060088111156107205760089250505061067e565b91505090565b60015481565b60085473ffffffffffffffffffffffffffffffffffffffff1681565b600061075584848461135d565b6107e5846107616111bb565b6107e085604051806060016040528060288152602001611ca56028913973ffffffffffffffffffffffffffffffffffffffff8a166000908152600360205260408120906107ac6111bb565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002054919063ffffffff61148716565b6111bf565b5060019392505050565b600890565b600061080f61080161069f565b60089063ffffffff6112d216565b905090565b60085474010000000000000000000000000000000000000000900460ff1681565b60006106956108426111bb565b846107e085600360006108536111bb565b73ffffffffffffffffffffffffffffffffffffffff908116825260208083019390935260409182016000908120918c16815292529020549063ffffffff61151e16565b600061080f6108af6276a700600863ffffffff61157816565b6108c6635f1b133762278d0063ffffffff61151e16565b9063ffffffff61151e16565b60055473ffffffffffffffffffffffffffffffffffffffff16331461093e576040805162461bcd60e51b815260206004820152600a60248201527f6f6e6c79206f776e657200000000000000000000000000000000000000000000604482015290519081900360640190fd5b60015467020324bb546e80009061095b908363ffffffff61151e16565b1161096f5761096a82826115d1565b6109bc565b6040805162461bcd60e51b815260206004820152601360248201527f4d617820737570706c7920657863656564656400000000000000000000000000604482015290519081900360640190fd5b5050565b6109ca33826116f6565b50565b60065473ffffffffffffffffffffffffffffffffffffffff1633146109f157600080fd5b60065460055460405173ffffffffffffffffffffffffffffffffffffffff92831692839216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a36005805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179055600680549091169055565b6000610699610a9983610ea9565b73ffffffffffffffffffffffffffffffffffffffff84166000908152600260205260409020549063ffffffff6112d216565b60026020526000908152604090205481565b60005460ff1615610b35576040805162461bcd60e51b815260206004820152601360248201527f616c726561647920696e697469616c697a656400000000000000000000000000604482015290519081900360640190fd5b600580547fffffffffffffffffffffffff00000000000000000000000000000000000000001633179055600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b635f1b133790565b60055473ffffffffffffffffffffffffffffffffffffffff1690565b60408051808201909152600381527f5452550000000000000000000000000000000000000000000000000000000000602082015290565b60055473ffffffffffffffffffffffffffffffffffffffff163314610c53576040805162461bcd60e51b815260206004820152600a60248201527f6f6e6c79206f776e657200000000000000000000000000000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8116610cbb576040805162461bcd60e51b815260206004820152601660248201527f63616e6e6f74206265207a65726f206164647265737300000000000000000000604482015290519081900360640190fd5b60085473ffffffffffffffffffffffffffffffffffffffff82811691161415610d2b576040805162461bcd60e51b815260206004820152601c60248201527f6d757374206265206e65772054696d654c6f636b526567697374727900000000604482015290519081900360640190fd5b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60085473ffffffffffffffffffffffffffffffffffffffff163314610dde576040805162461bcd60e51b815260206004820152601560248201527f6f6e6c792054696d654c6f636b52656769737472790000000000000000000000604482015290519081900360640190fd5b33600090815260026020526040902054811115610e42576040805162461bcd60e51b815260206004820152601460248201527f696e73756666696369656e742062616c616e6365000000000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260076020526040902054610e78908263ffffffff61151e16565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600760205260409020556109bc33838361135d565b600061069960086106fe610ebb6107f4565b73ffffffffffffffffffffffffffffffffffffffff86166000908152600760205260409020549063ffffffff61157816565b60055473ffffffffffffffffffffffffffffffffffffffff163314610f59576040805162461bcd60e51b815260206004820152600a60248201527f6f6e6c79206f776e657200000000000000000000000000000000000000000000604482015290519081900360640190fd5b600880547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000179055565b600080610fa561069f565b905080610fb957635f1b133791505061067e565b6107206108af826276a70063ffffffff61157816565b6000610695610fdc6111bb565b846107e085604051806060016040528060258152602001611d3760259139600360006110066111bb565b73ffffffffffffffffffffffffffffffffffffffff908116825260208083019390935260409182016000908120918d1681529252902054919063ffffffff61148716565b60006106956110576111bb565b848461135d565b60008061106961069f565b9050600881141561109d577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff91505061067e565b806110c0576110b86276a7006108c662278d006108c6610f9a565b91505061067e565b6107206276a7006108c6610f9a565b600360209081526000928352604080842090915290825290205481565b60065473ffffffffffffffffffffffffffffffffffffffff1690565b60055473ffffffffffffffffffffffffffffffffffffffff163314611174576040805162461bcd60e51b815260206004820152600a60248201527f6f6e6c79206f776e657200000000000000000000000000000000000000000000604482015290519081900360640190fd5b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b3390565b73ffffffffffffffffffffffffffffffffffffffff83166112115760405162461bcd60e51b8152600401808060200182810382526024815260200180611d136024913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82166112635760405162461bcd60e51b8152600401808060200182810382526022815260200180611c3c6022913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff808416600081815260036020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b600061131483836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611487565b9392505050565b600061131483836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506117d7565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600260205260409020548111156113d7576040805162461bcd60e51b815260206004820152601460248201527f696e73756666696369656e742062616c616e6365000000000000000000000000604482015290519081900360640190fd5b60085474010000000000000000000000000000000000000000900460ff1615801561141c575060055473ffffffffffffffffffffffffffffffffffffffff8381169116145b156114305761142b838261183c565b611482565b8061143a84610a8b565b10156114775760405162461bcd60e51b8152600401808060200182810382526023815260200180611bf76023913960400191505060405180910390fd5b6114828383836118ed565b505050565b600081848411156115165760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156114db5781810151838201526020016114c3565b50505050905090810190601f1680156115085780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600082820183811015611314576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60008261158757506000610699565b8282028284828161159457fe5b04146113145760405162461bcd60e51b8152600401808060200182810382526021815260200180611c846021913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216611639576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b61164560008383611482565b600154611658908263ffffffff61151e16565b60015573ffffffffffffffffffffffffffffffffffffffff8216600090815260026020526040902054611691908263ffffffff61151e16565b73ffffffffffffffffffffffffffffffffffffffff831660008181526002602090815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260026020526040902054811115611770576040805162461bcd60e51b815260206004820152601460248201527f696e73756666696369656e742062616c616e6365000000000000000000000000604482015290519081900360640190fd5b8061177a83610a8b565b10156117cd576040805162461bcd60e51b815260206004820152601f60248201527f617474656d7074696e6720746f206275726e206c6f636b65642066756e647300604482015290519081900360640190fd5b6109bc8282611a97565b600081836118265760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156114db5781810151838201526020016114c3565b50600083858161183257fe5b0495945050505050565b600061184783610a8b565b9050818110156118cc576118a561185c6107f4565b73ffffffffffffffffffffffffffffffffffffffff85166000908152600260205260409020546106fe90600890611899908763ffffffff6112d216565b9063ffffffff61157816565b73ffffffffffffffffffffffffffffffffffffffff84166000908152600760205260409020555b60055461148290849073ffffffffffffffffffffffffffffffffffffffff16845b73ffffffffffffffffffffffffffffffffffffffff831661193f5760405162461bcd60e51b8152600401808060200182810382526025815260200180611cee6025913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82166119915760405162461bcd60e51b8152600401808060200182810382526023815260200180611bd46023913960400191505060405180910390fd5b61199c838383611482565b6119ec81604051806060016040528060268152602001611c5e6026913973ffffffffffffffffffffffffffffffffffffffff8616600090815260026020526040902054919063ffffffff61148716565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152600260205260408082209390935590841681522054611a2e908263ffffffff61151e16565b73ffffffffffffffffffffffffffffffffffffffff80841660008181526002602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b73ffffffffffffffffffffffffffffffffffffffff8216611ae95760405162461bcd60e51b8152600401808060200182810382526021815260200180611ccd6021913960400191505060405180910390fd5b611af582600083611482565b611b4581604051806060016040528060228152602001611c1a6022913973ffffffffffffffffffffffffffffffffffffffff8516600090815260026020526040902054919063ffffffff61148716565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260026020526040902055600154611b7e908263ffffffff6112d216565b60015560408051828152905160009173ffffffffffffffffffffffffffffffffffffffff8516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a3505056fe45524332303a207472616e7366657220746f20746865207a65726f2061646472657373617474656d7074696e6720746f207472616e73666572206c6f636b65642066756e647345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e6365536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7745524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa26469706673582212202f6a9db7470493959023721b92468856acbe69d0704d6b42b5cab5a3768f1c8264736f6c634300060a0033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101f05760003560e01c806370a082311161010f5780639c7e1a9e116100a2578063aea0e78b11610071578063aea0e78b146105cb578063dd62ed3e146105d3578063e30c39781461060e578063f2fde38b14610616576101f0565b80639c7e1a9e146105495780639cb118bf14610551578063a457c2d714610559578063a9059cbb14610592576101f0565b806395d89b41116100de57806395d89b41146104a2578063962399e2146104aa57806397671bea146104dd5780639ae697bf14610516576101f0565b806370a08231146104575780638129fc1c1461048a578063881ed6db146104925780638da5cb5b1461049a576101f0565b8063313ce5671161018757806340c10f191161015657806340c10f19146103c457806342966c68146103ff5780634e71e0c81461041c5780635e0fac2e14610424576101f0565b8063313ce56714610355578063335f57531461037b57806339509351146103835780633a98d88e146103bc576101f0565b8063238189a8116101c3578063238189a8146102e157806323b872dd146103125780632e440403146103555780632f38466214610373576101f0565b806306fdde03146101f5578063095ea7b31461027257806315cb7cfa146102bf57806318160ddd146102d9575b600080fd5b6101fd610649565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561023757818101518382015260200161021f565b50505050905090810190601f1680156102645780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102ab6004803603604081101561028857600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610681565b604080519115158252519081900360200190f35b6102c761069f565b60408051918252519081900360200190f35b6102c7610726565b6102e961072c565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6102ab6004803603606081101561032857600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135610748565b61035d6107ef565b6040805160ff9092168252519081900360200190f35b6102c76107f4565b6102ab610814565b6102ab6004803603604081101561039957600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610835565b6102c7610896565b6103fd600480360360408110156103da57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356108d2565b005b6103fd6004803603602081101561041557600080fd5b50356109c0565b6103fd6109cd565b6102c76004803603602081101561043a57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610a8b565b6102c76004803603602081101561046d57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610acb565b6103fd610add565b6102c7610b8c565b6102e9610b94565b6101fd610bb0565b6103fd600480360360208110156104c057600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610be7565b6103fd600480360360408110156104f357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610d72565b6102c76004803603602081101561052c57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610ea9565b6103fd610eed565b6102c7610f9a565b6102ab6004803603604081101561056f57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610fcf565b6102ab600480360360408110156105a857600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813516906020013561104a565b6102c761105e565b6102c7600480360360408110156105e957600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166110cf565b6102e96110ec565b6103fd6004803603602081101561062c57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611108565b60408051808201909152600681527f547275654669000000000000000000000000000000000000000000000000000060208201525b90565b600061069561068e6111bb565b84846111bf565b5060015b92915050565b6000635f1b13374210156106b55750600061067e565b60006106cb42635f1b133763ffffffff6112d216565b905062278d008110156106e257600091505061067e565b600061070a6276a7006106fe8462278d0063ffffffff6112d216565b9063ffffffff61131b16565b905060088111156107205760089250505061067e565b91505090565b60015481565b60085473ffffffffffffffffffffffffffffffffffffffff1681565b600061075584848461135d565b6107e5846107616111bb565b6107e085604051806060016040528060288152602001611ca56028913973ffffffffffffffffffffffffffffffffffffffff8a166000908152600360205260408120906107ac6111bb565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002054919063ffffffff61148716565b6111bf565b5060019392505050565b600890565b600061080f61080161069f565b60089063ffffffff6112d216565b905090565b60085474010000000000000000000000000000000000000000900460ff1681565b60006106956108426111bb565b846107e085600360006108536111bb565b73ffffffffffffffffffffffffffffffffffffffff908116825260208083019390935260409182016000908120918c16815292529020549063ffffffff61151e16565b600061080f6108af6276a700600863ffffffff61157816565b6108c6635f1b133762278d0063ffffffff61151e16565b9063ffffffff61151e16565b60055473ffffffffffffffffffffffffffffffffffffffff16331461093e576040805162461bcd60e51b815260206004820152600a60248201527f6f6e6c79206f776e657200000000000000000000000000000000000000000000604482015290519081900360640190fd5b60015467020324bb546e80009061095b908363ffffffff61151e16565b1161096f5761096a82826115d1565b6109bc565b6040805162461bcd60e51b815260206004820152601360248201527f4d617820737570706c7920657863656564656400000000000000000000000000604482015290519081900360640190fd5b5050565b6109ca33826116f6565b50565b60065473ffffffffffffffffffffffffffffffffffffffff1633146109f157600080fd5b60065460055460405173ffffffffffffffffffffffffffffffffffffffff92831692839216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a36005805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179055600680549091169055565b6000610699610a9983610ea9565b73ffffffffffffffffffffffffffffffffffffffff84166000908152600260205260409020549063ffffffff6112d216565b60026020526000908152604090205481565b60005460ff1615610b35576040805162461bcd60e51b815260206004820152601360248201527f616c726561647920696e697469616c697a656400000000000000000000000000604482015290519081900360640190fd5b600580547fffffffffffffffffffffffff00000000000000000000000000000000000000001633179055600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b635f1b133790565b60055473ffffffffffffffffffffffffffffffffffffffff1690565b60408051808201909152600381527f5452550000000000000000000000000000000000000000000000000000000000602082015290565b60055473ffffffffffffffffffffffffffffffffffffffff163314610c53576040805162461bcd60e51b815260206004820152600a60248201527f6f6e6c79206f776e657200000000000000000000000000000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8116610cbb576040805162461bcd60e51b815260206004820152601660248201527f63616e6e6f74206265207a65726f206164647265737300000000000000000000604482015290519081900360640190fd5b60085473ffffffffffffffffffffffffffffffffffffffff82811691161415610d2b576040805162461bcd60e51b815260206004820152601c60248201527f6d757374206265206e65772054696d654c6f636b526567697374727900000000604482015290519081900360640190fd5b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60085473ffffffffffffffffffffffffffffffffffffffff163314610dde576040805162461bcd60e51b815260206004820152601560248201527f6f6e6c792054696d654c6f636b52656769737472790000000000000000000000604482015290519081900360640190fd5b33600090815260026020526040902054811115610e42576040805162461bcd60e51b815260206004820152601460248201527f696e73756666696369656e742062616c616e6365000000000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260076020526040902054610e78908263ffffffff61151e16565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600760205260409020556109bc33838361135d565b600061069960086106fe610ebb6107f4565b73ffffffffffffffffffffffffffffffffffffffff86166000908152600760205260409020549063ffffffff61157816565b60055473ffffffffffffffffffffffffffffffffffffffff163314610f59576040805162461bcd60e51b815260206004820152600a60248201527f6f6e6c79206f776e657200000000000000000000000000000000000000000000604482015290519081900360640190fd5b600880547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000179055565b600080610fa561069f565b905080610fb957635f1b133791505061067e565b6107206108af826276a70063ffffffff61157816565b6000610695610fdc6111bb565b846107e085604051806060016040528060258152602001611d3760259139600360006110066111bb565b73ffffffffffffffffffffffffffffffffffffffff908116825260208083019390935260409182016000908120918d1681529252902054919063ffffffff61148716565b60006106956110576111bb565b848461135d565b60008061106961069f565b9050600881141561109d577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff91505061067e565b806110c0576110b86276a7006108c662278d006108c6610f9a565b91505061067e565b6107206276a7006108c6610f9a565b600360209081526000928352604080842090915290825290205481565b60065473ffffffffffffffffffffffffffffffffffffffff1690565b60055473ffffffffffffffffffffffffffffffffffffffff163314611174576040805162461bcd60e51b815260206004820152600a60248201527f6f6e6c79206f776e657200000000000000000000000000000000000000000000604482015290519081900360640190fd5b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b3390565b73ffffffffffffffffffffffffffffffffffffffff83166112115760405162461bcd60e51b8152600401808060200182810382526024815260200180611d136024913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82166112635760405162461bcd60e51b8152600401808060200182810382526022815260200180611c3c6022913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff808416600081815260036020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b600061131483836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611487565b9392505050565b600061131483836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506117d7565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600260205260409020548111156113d7576040805162461bcd60e51b815260206004820152601460248201527f696e73756666696369656e742062616c616e6365000000000000000000000000604482015290519081900360640190fd5b60085474010000000000000000000000000000000000000000900460ff1615801561141c575060055473ffffffffffffffffffffffffffffffffffffffff8381169116145b156114305761142b838261183c565b611482565b8061143a84610a8b565b10156114775760405162461bcd60e51b8152600401808060200182810382526023815260200180611bf76023913960400191505060405180910390fd5b6114828383836118ed565b505050565b600081848411156115165760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156114db5781810151838201526020016114c3565b50505050905090810190601f1680156115085780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600082820183811015611314576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60008261158757506000610699565b8282028284828161159457fe5b04146113145760405162461bcd60e51b8152600401808060200182810382526021815260200180611c846021913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216611639576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b61164560008383611482565b600154611658908263ffffffff61151e16565b60015573ffffffffffffffffffffffffffffffffffffffff8216600090815260026020526040902054611691908263ffffffff61151e16565b73ffffffffffffffffffffffffffffffffffffffff831660008181526002602090815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260026020526040902054811115611770576040805162461bcd60e51b815260206004820152601460248201527f696e73756666696369656e742062616c616e6365000000000000000000000000604482015290519081900360640190fd5b8061177a83610a8b565b10156117cd576040805162461bcd60e51b815260206004820152601f60248201527f617474656d7074696e6720746f206275726e206c6f636b65642066756e647300604482015290519081900360640190fd5b6109bc8282611a97565b600081836118265760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156114db5781810151838201526020016114c3565b50600083858161183257fe5b0495945050505050565b600061184783610a8b565b9050818110156118cc576118a561185c6107f4565b73ffffffffffffffffffffffffffffffffffffffff85166000908152600260205260409020546106fe90600890611899908763ffffffff6112d216565b9063ffffffff61157816565b73ffffffffffffffffffffffffffffffffffffffff84166000908152600760205260409020555b60055461148290849073ffffffffffffffffffffffffffffffffffffffff16845b73ffffffffffffffffffffffffffffffffffffffff831661193f5760405162461bcd60e51b8152600401808060200182810382526025815260200180611cee6025913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82166119915760405162461bcd60e51b8152600401808060200182810382526023815260200180611bd46023913960400191505060405180910390fd5b61199c838383611482565b6119ec81604051806060016040528060268152602001611c5e6026913973ffffffffffffffffffffffffffffffffffffffff8616600090815260026020526040902054919063ffffffff61148716565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152600260205260408082209390935590841681522054611a2e908263ffffffff61151e16565b73ffffffffffffffffffffffffffffffffffffffff80841660008181526002602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b73ffffffffffffffffffffffffffffffffffffffff8216611ae95760405162461bcd60e51b8152600401808060200182810382526021815260200180611ccd6021913960400191505060405180910390fd5b611af582600083611482565b611b4581604051806060016040528060228152602001611c1a6022913973ffffffffffffffffffffffffffffffffffffffff8516600090815260026020526040902054919063ffffffff61148716565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260026020526040902055600154611b7e908263ffffffff6112d216565b60015560408051828152905160009173ffffffffffffffffffffffffffffffffffffffff8516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a3505056fe45524332303a207472616e7366657220746f20746865207a65726f2061646472657373617474656d7074696e6720746f207472616e73666572206c6f636b65642066756e647345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e6365536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7745524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa26469706673582212202f6a9db7470493959023721b92468856acbe69d0704d6b42b5cab5a3768f1c8264736f6c634300060a0033
Deployed Bytecode Sourcemap
48140:1232:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49172:95;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32438:160;;;;;;;;;;;;;;;;-1:-1:-1;32438:160:0;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;44811:889;;;:::i;:::-;;;;;;;;;;;;;;;;17609:26;;;:::i;40113:31::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;33072:310;;;;;;;;;;;;;;;;-1:-1:-1;33072:310:0;;;;;;;;;;;;;;;;;;:::i;49089:75::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;45708:110;;;:::i;40203:25::-;;;:::i;33791:216::-;;;;;;;;;;;;;;;;-1:-1:-1;33791:216:0;;;;;;;;;:::i;47359:221::-;;;:::i;48665:233::-;;;;;;;;;;;;;;;;-1:-1:-1;48665:233:0;;;;;;;;;:::i;:::-;;48906:83;;;;;;;;;;;;;;;;-1:-1:-1;48906:83:0;;:::i;20934:235::-;;;:::i;44490:185::-;;;;;;;;;;;;;;;;-1:-1:-1;44490:185:0;;;;:::i;17644:44::-;;;;;;;;;;;;;;;;-1:-1:-1;17644:44:0;;;;:::i;48409:149::-;;;:::i;47707:87::-;;;:::i;19643:79::-;;;:::i;49275:94::-;;;:::i;40504:304::-;;;;;;;;;;;;;;;;-1:-1:-1;40504:304:0;;;;:::i;43580:375::-;;;;;;;;;;;;;;;;-1:-1:-1;43580:375:0;;;;;;;;;:::i;44098:207::-;;;;;;;;;;;;;;;;-1:-1:-1;44098:207:0;;;;:::i;40963:81::-;;;:::i;46730:480::-;;;:::i;34510:267::-;;;;;;;;;;;;;;;;-1:-1:-1;34510:267:0;;;;;;;;;:::i;32125:166::-;;;;;;;;;;;;;;;;-1:-1:-1;32125:166:0;;;;;;;;;:::i;45987:610::-;;;:::i;17695:64::-;;;;;;;;;;;;;;;;-1:-1:-1;17695:64:0;;;;;;;;;;;:::i;19730:93::-;;;:::i;20732:105::-;;;;;;;;;;;;;;;;-1:-1:-1;20732:105:0;;;;:::i;49172:95::-;49244:15;;;;;;;;;;;;;;;;;49172:95;;:::o;32438:160::-;32512:4;32529:39;32538:12;:10;:12::i;:::-;32552:7;32561:6;32529:8;:39::i;:::-;-1:-1:-1;32586:4:0;32438:160;;;;;:::o;44811:889::-;44856:7;39815:10;44939:15;:28;44935:69;;;-1:-1:-1;44991:1:0;44984:8;;44935:69;45086:18;45107:31;:15;39815:10;45107:31;:19;:31;:::i;:::-;45086:52;;39913:7;45248:10;:30;45244:71;;;45302:1;45295:8;;;;;45244:71;45429:25;45457:53;39997:7;45457:33;:10;39913:7;45457:33;:14;:33;:::i;:::-;:37;:53;:37;:53;:::i;:::-;45429:81;;40068:1;45576:17;:32;45572:84;;;40068:1;45625:19;;;;;;45572:84;45675:17;-1:-1:-1;;44811:889:0;:::o;17609:26::-;;;;:::o;40113:31::-;;;;;;:::o;33072:310::-;33169:4;33186:36;33196:6;33204:9;33215:6;33186:9;:36::i;:::-;33233:119;33242:6;33250:12;:10;:12::i;:::-;33264:87;33300:6;33264:87;;;;;;;;;;;;;;;;;:17;;;;;;;:9;:17;;;;;;33282:12;:10;:12::i;:::-;33264:31;;;;;;;;;;;;;-1:-1:-1;33264:31:0;;;:87;;:35;:87;:::i;:::-;33233:8;:119::i;:::-;-1:-1:-1;33370:4:0;33072:310;;;;;:::o;49089:75::-;49155:1;49089:75;:::o;45708:110::-;45751:7;45778:32;45795:14;:12;:14::i;:::-;40068:1;;45778:32;:16;:32;:::i;:::-;45771:39;;45708:110;:::o;40203:25::-;;;;;;;;;:::o;33791:216::-;33879:4;33896:81;33905:12;:10;:12::i;:::-;33919:7;33928:48;33965:10;33928:9;:23;33938:12;:10;:12::i;:::-;33928:23;;;;;;;;;;;;;;;;;;-1:-1:-1;33928:23:0;;;:32;;;;;;;;;;;:48;:36;:48;:::i;47359:221::-;47402:7;47501:71;47539:32;39997:7;40068:1;47539:32;:18;:32;:::i;:::-;47501:33;39815:10;39913:7;47501:33;:14;:33;:::i;:::-;:37;:71;:37;:71;:::i;48665:233::-;20328:6;;;;20314:10;:20;20306:43;;;;;-1:-1:-1;;;20306:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;48743:11:::1;::::0;48247:18:::1;::::0;48743:24:::1;::::0;48759:7;48743:24:::1;:15;:24;:::i;:::-;:38;48739:152;;48798:19;48804:3;48809:7;48798:5;:19::i;:::-;48739:152;;;48850:29;::::0;;-1:-1:-1;;;48850:29:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;48739:152;48665:233:::0;;:::o;48906:83::-;48956:25;48962:10;48974:6;48956:5;:25::i;:::-;48906:83;:::o;20934:235::-;20539:13;;;;20525:10;:27;20517:36;;;;;;21019:13:::1;::::0;21069:6:::1;::::0;21048:43:::1;::::0;21019:13:::1;::::0;;::::1;::::0;;;21069:6:::1;::::0;21048:43:::1;::::0;20995:21:::1;::::0;21048:43:::1;21102:6;:22:::0;;::::1;::::0;;::::1;::::0;;;::::1;;::::0;;21135:13:::1;:26:::0;;;;::::1;::::0;;20934:235::o;44490:185::-;44553:7;44621:46;44644:22;44658:7;44644:13;:22::i;:::-;44621:18;;;;;;;:9;:18;;;;;;;:46;:22;:46;:::i;17644:44::-;;;;;;;;;;;;;:::o;48409:149::-;48458:10;;;;48457:11;48449:43;;;;;-1:-1:-1;;;48449:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;48503:6;:19;;;;48512:10;48503:19;;;:6;48533:17;;;;48503:19;48533:17;;;48409:149::o;47707:87::-;39815:10;47707:87;:::o;19643:79::-;19708:6;;;;19643:79;:::o;49275:94::-;49349:12;;;;;;;;;;;;;;;;;49275:94;:::o;40504:304::-;20328:6;;;;20314:10;:20;20306:43;;;;;-1:-1:-1;;;20306:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;40600:33:::1;::::0;::::1;40592:68;;;::::0;;-1:-1:-1;;;40592:68:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;40702:16;::::0;::::1;40679:39:::0;;::::1;40702:16:::0;::::1;40679:39;;40671:80;;;::::0;;-1:-1:-1;;;40671:80:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;40762:16;:38:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;40504:304::o;43580:375::-;40302:16;;;;40288:10;:30;40280:64;;;;;-1:-1:-1;;;40280:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;43697:10:::1;43687:21;::::0;;;:9:::1;:21;::::0;;;;;:31;-1:-1:-1;43687:31:0::1;43679:64;;;::::0;;-1:-1:-1;;;43679:64:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;43827:22;::::0;::::1;;::::0;;;:12:::1;:22;::::0;;;;;:34:::1;::::0;43854:6;43827:34:::1;:26;:34;:::i;:::-;43802:22;::::0;::::1;;::::0;;;:12:::1;:22;::::0;;;;:59;43908:39:::1;43918:10;43815:8:::0;43940:6;43908:9:::1;:39::i;44098:207::-:0;44159:7;44240:57;40068:1;44240:39;44266:12;:10;:12::i;:::-;44240:21;;;;;;;:12;:21;;;;;;;:39;:25;:39;:::i;40963:81::-;20328:6;;;;20314:10;:20;20306:43;;;;;-1:-1:-1;;;20306:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;41016:13:::1;:20:::0;;;::::1;::::0;::::1;::::0;;40963:81::o;46730:480::-;46774:7;46834:14;46851;:12;:14::i;:::-;46834:31;-1:-1:-1;46938:11:0;46934:61;;39815:10;46966:17;;;;;46934:61;47137:65;47175:26;:6;39997:7;47175:26;:10;:26;:::i;34510:267::-;34603:4;34620:127;34629:12;:10;:12::i;:::-;34643:7;34652:94;34689:15;34652:94;;;;;;;;;;;;;;;;;:9;:23;34662:12;:10;:12::i;:::-;34652:23;;;;;;;;;;;;;;;;;;-1:-1:-1;34652:23:0;;;:32;;;;;;;;;;;:94;;:36;:94;:::i;32125:166::-;32202:4;32219:42;32229:12;:10;:12::i;:::-;32243:9;32254:6;32219:9;:42::i;45987:610::-;46029:7;46089:14;46106;:12;:14::i;:::-;46089:31;;40068:1;46178:6;:22;46174:104;;;46263:2;46248:18;;;;;46174:104;46375:11;46371:107;;46410:56;39997:7;46410:36;39913:7;46410:13;:11;:13::i;:56::-;46403:63;;;;;46371:107;46556:33;39997:7;46556:13;:11;:13::i;17695:64::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;19730:93::-;19802:13;;;;19730:93;:::o;20732:105::-;20328:6;;;;20314:10;:20;20306:43;;;;;-1:-1:-1;;;20306:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;20805:13:::1;:24:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;20732:105::o;21746:106::-;21834:10;21746:106;:::o;37651:344::-;37753:19;;;37745:68;;;;-1:-1:-1;;;37745:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37832:21;;;37824:68;;;;-1:-1:-1;;;37824:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37905:16;;;;;;;;:9;:16;;;;;;;;:25;;;;;;;;;;;;;:34;;;37955:32;;;;;;;;;;;;;;;;;37651:344;;;:::o;3464:136::-;3522:7;3549:43;3553:1;3556;3549:43;;;;;;;;;;;;;;;;;:3;:43::i;:::-;3542:50;3464:136;-1:-1:-1;;;3464:136:0:o;5301:132::-;5359:7;5386:39;5390:1;5393;5386:39;;;;;;;;;;;;;;;;;:3;:39::i;41464:584::-;41598:16;;;;;;;:9;:16;;;;;;:26;-1:-1:-1;41598:26:0;41590:59;;;;;-1:-1:-1;;;41590:59:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;41737:13;;;;;;;41736:14;:31;;;;-1:-1:-1;41761:6:0;;;41754:13;;;41761:6;;41754:13;41736:31;41732:115;;;41784:30;41800:5;41807:6;41784:15;:30::i;:::-;41829:7;;41732:115;41948:6;41922:22;41938:5;41922:15;:22::i;:::-;:32;;41914:80;;;;-1:-1:-1;;;41914:80:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42005:35;42021:5;42028:3;42033:6;42005:15;:35::i;:::-;41464:584;;;:::o;3903:192::-;3989:7;4025:12;4017:6;;;;4009:29;;;;-1:-1:-1;;;4009:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;4061:5:0;;;3903:192::o;3000:181::-;3058:7;3090:5;;;3114:6;;;;3106:46;;;;;-1:-1:-1;;;3106:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;4354:471;4412:7;4657:6;4653:47;;-1:-1:-1;4687:1:0;4680:8;;4653:47;4724:5;;;4728:1;4724;:5;:1;4748:5;;;;;:10;4740:56;;;;-1:-1:-1;;;4740:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36087:376;36171:21;;;36163:65;;;;;-1:-1:-1;;;36163:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;36241:49;36270:1;36274:7;36283:6;36241:20;:49::i;:::-;36317:11;;:23;;36333:6;36317:23;:15;:23;:::i;:::-;36303:11;:37;36372:18;;;;;;;:9;:18;;;;;;:30;;36395:6;36372:30;:22;:30;:::i;:::-;36351:18;;;;;;;:9;:18;;;;;;;;:51;;;;36418:37;;;;;;;36351:18;;;;36418:37;;;;;;;;;;36087:376;;:::o;42995:268::-;43078:16;;;;;;;:9;:16;;;;;;:26;-1:-1:-1;43078:26:0;43070:59;;;;;-1:-1:-1;;;43070:59:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;43174:6;43148:22;43164:5;43148:15;:22::i;:::-;:32;;43140:76;;;;;-1:-1:-1;;;43140:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;43229:26;43241:5;43248:6;43229:11;:26::i;5929:278::-;6015:7;6050:12;6043:5;6035:28;;;;-1:-1:-1;;;6035:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6074:9;6090:1;6086;:5;;;;;;;5929:278;-1:-1:-1;;;;;5929:278:0:o;42259:527::-;42335:16;42354:22;42370:5;42354:15;:22::i;:::-;42335:41;;42404:6;42393:8;:17;42389:341;;;42654:64;42705:12;:10;:12::i;:::-;42654:16;;;;;;;:9;:16;;;;;;:46;;40068:1;;42654:28;;42675:6;42654:28;:20;:28;:::i;:::-;:32;:46;:32;:46;:::i;:64::-;42632:19;;;;;;;:12;:19;;;;;:86;42389:341;42763:6;;42740:38;;42756:5;;42763:6;;42771;35267:539;35373:20;;;35365:70;;;;-1:-1:-1;;;35365:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35454:23;;;35446:71;;;;-1:-1:-1;;;35446:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35530:47;35551:6;35559:9;35570:6;35530:20;:47::i;:::-;35610:71;35632:6;35610:71;;;;;;;;;;;;;;;;;:17;;;;;;;:9;:17;;;;;;;:71;;:21;:71;:::i;:::-;35590:17;;;;;;;;:9;:17;;;;;;:91;;;;35715:20;;;;;;;:32;;35740:6;35715:32;:24;:32;:::i;:::-;35692:20;;;;;;;;:9;:20;;;;;;;;;:55;;;;35763:35;;;;;;;35692:20;;35763:35;;;;;;;;;;;;;35267:539;;;:::o;36795:416::-;36879:21;;;36871:67;;;;-1:-1:-1;;;36871:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36951:49;36972:7;36989:1;36993:6;36951:20;:49::i;:::-;37034:68;37057:6;37034:68;;;;;;;;;;;;;;;;;:18;;;;;;;:9;:18;;;;;;;:68;;:22;:68;:::i;:::-;37013:18;;;;;;;:9;:18;;;;;:89;37127:11;;:23;;37143:6;37127:23;:15;:23;:::i;:::-;37113:11;:37;37166;;;;;;;;37192:1;;37166:37;;;;;;;;;;;;;36795:416;;:::o
Swarm Source
ipfs://2f6a9db7470493959023721b92468856acbe69d0704d6b42b5cab5a3768f1c82
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 25 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.