Feature Tip: Add private address tag to any address under My Name Tag !
Contract Overview
Balance:
0 Ether
EtherValue:
$0.00
More Info
My Name Tag:
Not Available, login to update
Txn Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
0xd993563f262f2e770a6c78279d531250e76bced89a34d178b88aa50c2514693f | 0x60806040 | 12369796 | 472 days 4 hrs ago | 0x35442a5eafb1dd68748e1279aac31be75d7ac1d6 | IN | Create: MappableToken | 0 Ether | 0.14183979 |
[ Download CSV Export ]
View more zero value Internal Transactions in Advanced View mode
Contract Name:
MappableToken
Compiler Version
v0.6.12+commit.27d51765
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-05-04 */ // SPDX-License-Identifier: MIT pragma solidity ^0.6.0; pragma experimental ABIEncoderV2; /** * @title Proxy * @dev Implements delegation of calls to other contracts, with proper * forwarding of return values and bubbling of failures. * It defines a fallback function that delegates all calls to the address * returned by the abstract _implementation() internal function. */ abstract contract Proxy { /** * @dev Fallback function. * Implemented entirely in `_fallback`. */ fallback () payable external { _fallback(); } receive () payable external { _fallback(); } /** * @return The Address of the implementation. */ function _implementation() virtual internal view returns (address); /** * @dev Delegates execution to an implementation contract. * This is a low level function that doesn't return to its internal call site. * It will return to the external caller whatever the implementation returns. * @param implementation Address to delegate. */ function _delegate(address implementation) internal { assembly { // Copy msg.data. We take full control of memory in this inline assembly // block because it will not return to Solidity code. We overwrite the // Solidity scratch pad at memory position 0. calldatacopy(0, 0, calldatasize()) // Call the implementation. // out and outsize are 0 because we don't know the size yet. let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0) // Copy the returned data. returndatacopy(0, 0, returndatasize()) switch result // delegatecall returns 0 on error. case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } /** * @dev Function that is run as the first thing in the fallback function. * Can be redefined in derived contracts to add functionality. * Redefinitions must call super._willFallback(). */ function _willFallback() virtual internal { } /** * @dev fallback implementation. * Extracted to enable manual triggering. */ function _fallback() internal { if(OpenZeppelinUpgradesAddress.isContract(msg.sender) && msg.data.length == 0 && gasleft() <= 2300) // for receive ETH only from other contract return; _willFallback(); _delegate(_implementation()); } } /** * @title BaseUpgradeabilityProxy * @dev This contract implements a proxy that allows to change the * implementation address to which it will delegate. * Such a change is called an implementation upgrade. */ abstract contract BaseUpgradeabilityProxy is Proxy { /** * @dev Emitted when the implementation is upgraded. * @param implementation Address of the new implementation. */ event Upgraded(address indexed implementation); /** * @dev Storage slot with the address of the current implementation. * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Returns the current implementation. * @return impl Address of the current implementation */ function _implementation() override internal view returns (address impl) { bytes32 slot = IMPLEMENTATION_SLOT; assembly { impl := sload(slot) } } /** * @dev Upgrades the proxy to a new implementation. * @param newImplementation Address of the new implementation. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Sets the implementation address of the proxy. * @param newImplementation Address of the new implementation. */ function _setImplementation(address newImplementation) internal { require(OpenZeppelinUpgradesAddress.isContract(newImplementation), "Cannot set a proxy implementation to a non-contract address"); bytes32 slot = IMPLEMENTATION_SLOT; assembly { sstore(slot, newImplementation) } } } /** * @title BaseAdminUpgradeabilityProxy * @dev This contract combines an upgradeability proxy with an authorization * mechanism for administrative tasks. * All external functions in this contract must be guarded by the * `ifAdmin` modifier. See ethereum/solidity#3864 for a Solidity * feature proposal that would enable this to be done automatically. */ contract BaseAdminUpgradeabilityProxy is BaseUpgradeabilityProxy { /** * @dev Emitted when the administration has been transferred. * @param previousAdmin Address of the previous admin. * @param newAdmin Address of the new admin. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Storage slot with the admin of the contract. * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Modifier to check whether the `msg.sender` is the admin. * If it is, it will run the function. Otherwise, it will delegate the call * to the implementation. */ modifier ifAdmin() { if (msg.sender == _admin()) { _; } else { _fallback(); } } /** * @return The address of the proxy admin. */ function admin() external ifAdmin returns (address) { return _admin(); } /** * @return The address of the implementation. */ function implementation() external ifAdmin returns (address) { return _implementation(); } /** * @dev Changes the admin of the proxy. * Only the current admin can call this function. * @param newAdmin Address to transfer proxy administration to. */ function changeAdmin(address newAdmin) external ifAdmin { require(newAdmin != address(0), "Cannot change the admin of a proxy to the zero address"); emit AdminChanged(_admin(), newAdmin); _setAdmin(newAdmin); } /** * @dev Upgrade the backing implementation of the proxy. * Only the admin can call this function. * @param newImplementation Address of the new implementation. */ function upgradeTo(address newImplementation) external ifAdmin { _upgradeTo(newImplementation); } /** * @dev Upgrade the backing implementation of the proxy and call a function * on the new implementation. * This is useful to initialize the proxied contract. * @param newImplementation Address of the new implementation. * @param data Data to send as msg.data in the low level call. * It should include the signature and the parameters of the function to be called, as described in * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding. */ function upgradeToAndCall(address newImplementation, bytes calldata data) payable external ifAdmin { _upgradeTo(newImplementation); (bool success,) = newImplementation.delegatecall(data); require(success); } /** * @return adm The admin slot. */ function _admin() internal view returns (address adm) { bytes32 slot = ADMIN_SLOT; assembly { adm := sload(slot) } } /** * @dev Sets the address of the proxy admin. * @param newAdmin Address of the new proxy admin. */ function _setAdmin(address newAdmin) internal { bytes32 slot = ADMIN_SLOT; assembly { sstore(slot, newAdmin) } } /** * @dev Only fall back when the sender is not the admin. */ function _willFallback() virtual override internal { require(msg.sender != _admin(), "Cannot call fallback function from the proxy admin"); //super._willFallback(); } } interface IAdminUpgradeabilityProxyView { function admin() external view returns (address); function implementation() external view returns (address); } /** * @title UpgradeabilityProxy * @dev Extends BaseUpgradeabilityProxy with a constructor for initializing * implementation and init data. */ abstract contract UpgradeabilityProxy is BaseUpgradeabilityProxy { /** * @dev Contract constructor. * @param _logic Address of the initial implementation. * @param _data Data to send as msg.data to the implementation to initialize the proxied contract. * It should include the signature and the parameters of the function to be called, as described in * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding. * This parameter is optional, if no data is given the initialization call to proxied contract will be skipped. */ constructor(address _logic, bytes memory _data) public payable { assert(IMPLEMENTATION_SLOT == bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)); _setImplementation(_logic); if(_data.length > 0) { (bool success,) = _logic.delegatecall(_data); require(success); } } //function _willFallback() virtual override internal { //super._willFallback(); //} } /** * @title AdminUpgradeabilityProxy * @dev Extends from BaseAdminUpgradeabilityProxy with a constructor for * initializing the implementation, admin, and init data. */ contract AdminUpgradeabilityProxy is BaseAdminUpgradeabilityProxy, UpgradeabilityProxy { /** * Contract constructor. * @param _logic address of the initial implementation. * @param _admin Address of the proxy administrator. * @param _data Data to send as msg.data to the implementation to initialize the proxied contract. * It should include the signature and the parameters of the function to be called, as described in * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding. * This parameter is optional, if no data is given the initialization call to proxied contract will be skipped. */ constructor(address _admin, address _logic, bytes memory _data) UpgradeabilityProxy(_logic, _data) public payable { assert(ADMIN_SLOT == bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)); _setAdmin(_admin); } function _willFallback() override(Proxy, BaseAdminUpgradeabilityProxy) internal { super._willFallback(); } } /** * @title InitializableUpgradeabilityProxy * @dev Extends BaseUpgradeabilityProxy with an initializer for initializing * implementation and init data. */ abstract contract InitializableUpgradeabilityProxy is BaseUpgradeabilityProxy { /** * @dev Contract initializer. * @param _logic Address of the initial implementation. * @param _data Data to send as msg.data to the implementation to initialize the proxied contract. * It should include the signature and the parameters of the function to be called, as described in * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding. * This parameter is optional, if no data is given the initialization call to proxied contract will be skipped. */ function initialize(address _logic, bytes memory _data) public payable { require(_implementation() == address(0)); assert(IMPLEMENTATION_SLOT == bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)); _setImplementation(_logic); if(_data.length > 0) { (bool success,) = _logic.delegatecall(_data); require(success); } } } /** * @title InitializableAdminUpgradeabilityProxy * @dev Extends from BaseAdminUpgradeabilityProxy with an initializer for * initializing the implementation, admin, and init data. */ contract InitializableAdminUpgradeabilityProxy is BaseAdminUpgradeabilityProxy, InitializableUpgradeabilityProxy { /** * Contract initializer. * @param _logic address of the initial implementation. * @param _admin Address of the proxy administrator. * @param _data Data to send as msg.data to the implementation to initialize the proxied contract. * It should include the signature and the parameters of the function to be called, as described in * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding. * This parameter is optional, if no data is given the initialization call to proxied contract will be skipped. */ function initialize(address _admin, address _logic, bytes memory _data) public payable { require(_implementation() == address(0)); InitializableUpgradeabilityProxy.initialize(_logic, _data); assert(ADMIN_SLOT == bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)); _setAdmin(_admin); } function _willFallback() override(Proxy, BaseAdminUpgradeabilityProxy) internal { super._willFallback(); } } interface IProxyFactory { function productImplementation() external view returns (address); function productImplementations(bytes32 name) external view returns (address); } /** * @title ProductProxy * @dev This contract implements a proxy that * it is deploied by ProxyFactory, * and it's implementation is stored in factory. */ contract ProductProxy is Proxy { /** * @dev Storage slot with the address of the ProxyFactory. * This is the keccak-256 hash of "eip1967.proxy.factory" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant FACTORY_SLOT = 0x7a45a402e4cb6e08ebc196f20f66d5d30e67285a2a8aa80503fa409e727a4af1; bytes32 internal constant NAME_SLOT = 0x4cd9b827ca535ceb0880425d70eff88561ecdf04dc32fcf7ff3b15c587f8a870; // bytes32(uint256(keccak256('eip1967.proxy.name')) - 1) function _name() virtual internal view returns (bytes32 name_) { bytes32 slot = NAME_SLOT; assembly { name_ := sload(slot) } } function _setName(bytes32 name_) internal { bytes32 slot = NAME_SLOT; assembly { sstore(slot, name_) } } /** * @dev Sets the factory address of the ProductProxy. * @param newFactory Address of the new factory. */ function _setFactory(address newFactory) internal { require(OpenZeppelinUpgradesAddress.isContract(newFactory), "Cannot set a factory to a non-contract address"); bytes32 slot = FACTORY_SLOT; assembly { sstore(slot, newFactory) } } /** * @dev Returns the factory. * @return factory_ Address of the factory. */ function _factory() internal view returns (address factory_) { bytes32 slot = FACTORY_SLOT; assembly { factory_ := sload(slot) } } /** * @dev Returns the current implementation. * @return Address of the current implementation */ function _implementation() virtual override internal view returns (address) { address factory_ = _factory(); if(OpenZeppelinUpgradesAddress.isContract(factory_)) return IProxyFactory(factory_).productImplementations(_name()); else return address(0); } } /** * @title InitializableProductProxy * @dev Extends ProductProxy with an initializer for initializing * factory and init data. */ contract InitializableProductProxy is ProductProxy { /** * @dev Contract initializer. * @param factory_ Address of the initial factory. * @param data_ Data to send as msg.data to the implementation to initialize the proxied contract. * It should include the signature and the parameters of the function to be called, as described in * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding. * This parameter is optional, if no data is given the initialization call to proxied contract will be skipped. */ function __InitializableProductProxy_init(address factory_, bytes32 name_, bytes memory data_) public payable { require(_factory() == address(0)); assert(FACTORY_SLOT == bytes32(uint256(keccak256('eip1967.proxy.factory')) - 1)); assert(NAME_SLOT == bytes32(uint256(keccak256('eip1967.proxy.name')) - 1)); _setFactory(factory_); _setName(name_); if(data_.length > 0) { (bool success,) = _implementation().delegatecall(data_); require(success); } } } /** * @title Initializable * * @dev Helper contract to support initializer functions. To use it, replace * the constructor with a function that has the `initializer` modifier. * WARNING: Unlike constructors, initializer functions must be manually * invoked. This applies both to deploying an Initializable contract, as well * as extending an Initializable contract via inheritance. * WARNING: When used with inheritance, manual care must be taken to not invoke * a parent initializer twice, or ensure that all initializers are idempotent, * because this is not dealt with automatically as with constructors. */ contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private initializing; /** * @dev Modifier to use in the initializer function of a contract. */ modifier initializer() { require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized"); bool isTopLevelCall = !initializing; if (isTopLevelCall) { initializing = true; initialized = true; } _; if (isTopLevelCall) { initializing = false; } } /// @dev Returns true if and only if the function is running in the constructor function isConstructor() private view returns (bool) { // extcodesize checks the size of the code stored in an address, and // address returns the current address. Since the code is still not // deployed when running a constructor, any checks on its code size will // yield zero, making it an effective way to detect if a contract is // under construction or not. address self = address(this); uint256 cs; assembly { cs := extcodesize(self) } return cs == 0; } // Reserved storage space to allow for layout changes in the future. uint256[50] private ______gap; } /* * @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. */ contract ContextUpgradeSafe is Initializable { // Empty internal constructor, to prevent people from mistakenly deploying // an instance of this contract, which should be used via inheritance. function __Context_init() internal initializer { __Context_init_unchained(); } function __Context_init_unchained() internal initializer { } 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; } uint256[50] private __gap; } /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ contract ReentrancyGuardUpgradeSafe is Initializable { bool private _notEntered; function __ReentrancyGuard_init() internal initializer { __ReentrancyGuard_init_unchained(); } function __ReentrancyGuard_init_unchained() internal initializer { // Storing an initial non-zero value makes deployment a bit more // expensive, but in exchange the refund on every call to nonReentrant // will be lower in amount. Since refunds are capped to a percetange of // the total transaction's gas, it is best to keep them low in cases // like this one, to increase the likelihood of the full refund coming // into effect. _notEntered = true; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_notEntered, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _notEntered = false; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _notEntered = true; } uint256[49] private __gap; } /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow, so we distribute return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2); } } /** * @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; } function sub0(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a - b : 0; } /** * @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) { // Solidity only automatically asserts when dividing by 0 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; } } /** * Utility library of inline functions on addresses * * Source https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-solidity/v2.1.3/contracts/utils/Address.sol * This contract is copied here and renamed from the original to avoid clashes in the compiled artifacts * when the user imports a zos-lib contract (that transitively causes this contract to be compiled and added to the * build/artifacts folder) as well as the vanilla Address implementation from an openzeppelin version. */ library OpenZeppelinUpgradesAddress { /** * 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 account address of the account to check * @return whether the target address is a contract */ function isContract(address account) 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. // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } } /** * @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 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); } /** * @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 {ERC20MinterPauser}. * * 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}. */ contract ERC20UpgradeSafe is Initializable, ContextUpgradeSafe, IERC20 { using SafeMath for uint256; using Address for address; mapping (address => uint256) private _balances; mapping (address => mapping (address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; uint8 private _decimals; /** * @dev Sets the values for {name} and {symbol}, initializes {decimals} with * a default value of 18. * * To select a different value for {decimals}, use {_setupDecimals}. * * All three of these values are immutable: they can only be set once during * construction. */ function __ERC20_init(string memory name, string memory symbol) internal initializer { __Context_init_unchained(); __ERC20_init_unchained(name, symbol); } function __ERC20_init_unchained(string memory name, string memory symbol) internal initializer { _name = name; _symbol = symbol; _decimals = 18; } /** * @dev Returns the name of the token. */ function name() public view returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view returns (string memory) { return _symbol; } /** * @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 view returns (uint8) { return _decimals; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view override returns (uint256) { return _balances[account]; } /** * @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 override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override 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 override returns (bool) { _transfer(sender, recipient, amount); if(sender != _msgSender() && _allowances[sender][_msgSender()] != uint(-1)) _approve(sender, _msgSender(), _allowances[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, _allowances[_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, _allowances[_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); _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance"); _balances[recipient] = _balances[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); _balances[account] = _balances[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); _balances[account] = _balances[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"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Sets {decimals} to a value other than the default one of 18. * * WARNING: This function should only be called from the constructor. Most * applications that interact with token contracts will not expect * {decimals} to ever change, and may work incorrectly if it does. */ function _setupDecimals(uint8 decimals_) internal { _decimals = decimals_; } /** * @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]. */ function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { } uint256[44] private __gap; } /** * @dev Extension of {ERC20} that adds a cap to the supply of tokens. */ abstract contract ERC20CappedUpgradeSafe is Initializable, ERC20UpgradeSafe { uint256 private _cap; /** * @dev Sets the value of the `cap`. This value is immutable, it can only be * set once during construction. */ function __ERC20Capped_init(uint256 cap) internal initializer { __Context_init_unchained(); __ERC20Capped_init_unchained(cap); } function __ERC20Capped_init_unchained(uint256 cap) internal initializer { require(cap > 0, "ERC20Capped: cap is 0"); _cap = cap; } /** * @dev Returns the cap on the token's total supply. */ function cap() virtual public view returns (uint256) { return _cap; } /** * @dev See {ERC20-_beforeTokenTransfer}. * * Requirements: * * - minted tokens must not cause the total supply to go over the cap. */ function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override { super._beforeTokenTransfer(from, to, amount); if (from == address(0)) { // When minting tokens require(totalSupply().add(amount) <= _cap, "ERC20Capped: cap exceeded"); } } uint256[49] private __gap; } /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * 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 { using SafeMath for uint256; using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).add(value); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. // A Solidity high level call has three parts: // 1. The target address is checked to verify it contains contract code // 2. The call itself is made, and success asserted // 3. The return value is decoded, which in turn checks the size of the returned data. // solhint-disable-next-line max-line-length require(address(token).isContract(), "SafeERC20: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = address(token).call(data); require(success, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } // https://github.com/hamdiallam/Solidity-RLP/blob/master/contracts/RLPReader.sol /* * @author Hamdi Allam [email protected] * Please reach out with any questions or concerns */ pragma solidity >=0.5.0 <0.7.0; library RLPReader { uint8 constant STRING_SHORT_START = 0x80; uint8 constant STRING_LONG_START = 0xb8; uint8 constant LIST_SHORT_START = 0xc0; uint8 constant LIST_LONG_START = 0xf8; uint8 constant WORD_SIZE = 32; struct RLPItem { uint len; uint memPtr; } struct Iterator { RLPItem item; // Item that's being iterated over. uint nextPtr; // Position of the next item in the list. } /* * @dev Returns the next element in the iteration. Reverts if it has not next element. * @param self The iterator. * @return The next element in the iteration. */ function next(Iterator memory self) internal pure returns (RLPItem memory) { require(hasNext(self)); uint ptr = self.nextPtr; uint itemLength = _itemLength(ptr); self.nextPtr = ptr + itemLength; return RLPItem(itemLength, ptr); } /* * @dev Returns true if the iteration has more elements. * @param self The iterator. * @return true if the iteration has more elements. */ function hasNext(Iterator memory self) internal pure returns (bool) { RLPItem memory item = self.item; return self.nextPtr < item.memPtr + item.len; } /* * @param item RLP encoded bytes */ function toRlpItem(bytes memory item) internal pure returns (RLPItem memory) { uint memPtr; assembly { memPtr := add(item, 0x20) } return RLPItem(item.length, memPtr); } /* * @dev Create an iterator. Reverts if item is not a list. * @param self The RLP item. * @return An 'Iterator' over the item. */ function iterator(RLPItem memory self) internal pure returns (Iterator memory) { require(isList(self)); uint ptr = self.memPtr + _payloadOffset(self.memPtr); return Iterator(self, ptr); } /* * @param the RLP item. */ function rlpLen(RLPItem memory item) internal pure returns (uint) { return item.len; } /* * @param the RLP item. * @return (memPtr, len) pair: location of the item's payload in memory. */ function payloadLocation(RLPItem memory item) internal pure returns (uint, uint) { uint offset = _payloadOffset(item.memPtr); uint memPtr = item.memPtr + offset; uint len = item.len - offset; // data length return (memPtr, len); } /* * @param the RLP item. */ function payloadLen(RLPItem memory item) internal pure returns (uint) { (, uint len) = payloadLocation(item); return len; } /* * @param the RLP item containing the encoded list. */ function toList(RLPItem memory item) internal pure returns (RLPItem[] memory) { require(isList(item)); uint items = numItems(item); RLPItem[] memory result = new RLPItem[](items); uint memPtr = item.memPtr + _payloadOffset(item.memPtr); uint dataLen; for (uint i = 0; i < items; i++) { dataLen = _itemLength(memPtr); result[i] = RLPItem(dataLen, memPtr); memPtr = memPtr + dataLen; } return result; } // @return indicator whether encoded payload is a list. negate this function call for isData. function isList(RLPItem memory item) internal pure returns (bool) { if (item.len == 0) return false; uint8 byte0; uint memPtr = item.memPtr; assembly { byte0 := byte(0, mload(memPtr)) } if (byte0 < LIST_SHORT_START) return false; return true; } /* * @dev A cheaper version of keccak256(toRlpBytes(item)) that avoids copying memory. * @return keccak256 hash of RLP encoded bytes. */ function rlpBytesKeccak256(RLPItem memory item) internal pure returns (bytes32) { uint256 ptr = item.memPtr; uint256 len = item.len; bytes32 result; assembly { result := keccak256(ptr, len) } return result; } /* * @dev A cheaper version of keccak256(toBytes(item)) that avoids copying memory. * @return keccak256 hash of the item payload. */ function payloadKeccak256(RLPItem memory item) internal pure returns (bytes32) { (uint memPtr, uint len) = payloadLocation(item); bytes32 result; assembly { result := keccak256(memPtr, len) } return result; } /** RLPItem conversions into data types **/ // @returns raw rlp encoding in bytes function toRlpBytes(RLPItem memory item) internal pure returns (bytes memory) { bytes memory result = new bytes(item.len); if (result.length == 0) return result; uint ptr; assembly { ptr := add(0x20, result) } copy(item.memPtr, ptr, item.len); return result; } // any non-zero byte except "0x80" is considered true function toBoolean(RLPItem memory item) internal pure returns (bool) { require(item.len == 1); uint result; uint memPtr = item.memPtr; assembly { result := byte(0, mload(memPtr)) } // SEE Github Issue #5. // Summary: Most commonly used RLP libraries (i.e Geth) will encode // "0" as "0x80" instead of as "0". We handle this edge case explicitly // here. if (result == 0 || result == STRING_SHORT_START) { return false; } else { return true; } } function toAddress(RLPItem memory item) internal pure returns (address) { // 1 byte for the length prefix require(item.len == 21); return address(toUint(item)); } function toUint(RLPItem memory item) internal pure returns (uint) { require(item.len > 0 && item.len <= 33); (uint memPtr, uint len) = payloadLocation(item); uint result; assembly { result := mload(memPtr) // shfit to the correct location if neccesary if lt(len, 32) { result := div(result, exp(256, sub(32, len))) } } return result; } // enforces 32 byte length function toUintStrict(RLPItem memory item) internal pure returns (uint) { // one byte prefix require(item.len == 33); uint result; uint memPtr = item.memPtr + 1; assembly { result := mload(memPtr) } return result; } function toBytes(RLPItem memory item) internal pure returns (bytes memory) { require(item.len > 0); (uint memPtr, uint len) = payloadLocation(item); bytes memory result = new bytes(len); uint destPtr; assembly { destPtr := add(0x20, result) } copy(memPtr, destPtr, len); return result; } /* * Private Helpers */ // @return number of payload items inside an encoded list. function numItems(RLPItem memory item) private pure returns (uint) { if (item.len == 0) return 0; uint count = 0; uint currPtr = item.memPtr + _payloadOffset(item.memPtr); uint endPtr = item.memPtr + item.len; while (currPtr < endPtr) { currPtr = currPtr + _itemLength(currPtr); // skip over an item count++; } return count; } // @return entire rlp item byte length function _itemLength(uint memPtr) private pure returns (uint) { uint itemLen; uint byte0; assembly { byte0 := byte(0, mload(memPtr)) } if (byte0 < STRING_SHORT_START) itemLen = 1; else if (byte0 < STRING_LONG_START) itemLen = byte0 - STRING_SHORT_START + 1; else if (byte0 < LIST_SHORT_START) { assembly { let byteLen := sub(byte0, 0xb7) // # of bytes the actual length is memPtr := add(memPtr, 1) // skip over the first byte /* 32 byte word size */ let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to get the len itemLen := add(dataLen, add(byteLen, 1)) } } else if (byte0 < LIST_LONG_START) { itemLen = byte0 - LIST_SHORT_START + 1; } else { assembly { let byteLen := sub(byte0, 0xf7) memPtr := add(memPtr, 1) let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to the correct length itemLen := add(dataLen, add(byteLen, 1)) } } return itemLen; } // @return number of bytes until the data function _payloadOffset(uint memPtr) private pure returns (uint) { uint byte0; assembly { byte0 := byte(0, mload(memPtr)) } if (byte0 < STRING_SHORT_START) return 0; else if (byte0 < STRING_LONG_START || (byte0 >= LIST_SHORT_START && byte0 < LIST_LONG_START)) return 1; else if (byte0 < LIST_SHORT_START) // being explicit return byte0 - (STRING_LONG_START - 1) + 1; else return byte0 - (LIST_LONG_START - 1) + 1; } /* * @param src Pointer to source * @param dest Pointer to destination * @param len Amount of memory to copy from the source */ function copy(uint src, uint dest, uint len) private pure { if (len == 0) return; // copy as many word sizes as possible for (; len >= WORD_SIZE; len -= WORD_SIZE) { assembly { mstore(dest, mload(src)) } src += WORD_SIZE; dest += WORD_SIZE; } // left over bytes. Mask is used to remove unwanted bytes from the word uint mask = 256 ** (WORD_SIZE - len) - 1; assembly { let srcpart := and(mload(src), not(mask)) // zero out src let destpart := and(mload(dest), mask) // retrieve the bytes mstore(dest, or(destpart, srcpart)) } } } // https://github.com/bakaoh/solidity-rlp-encode/blob/master/contracts/RLPEncode.sol /** * @title RLPEncode * @dev A simple RLP encoding library. * @author Bakaoh */ library RLPEncode { /* * Internal functions */ /** * @dev RLP encodes a byte string. * @param self The byte string to encode. * @return The RLP encoded string in bytes. */ function encodeBytes(bytes memory self) internal pure returns (bytes memory) { bytes memory encoded; if (self.length == 1 && uint8(self[0]) <= 128) { encoded = self; } else { encoded = concat(encodeLength(self.length, 128), self); } return encoded; } /** * @dev RLP encodes a list of RLP encoded byte byte strings. * @param self The list of RLP encoded byte strings. * @return The RLP encoded list of items in bytes. */ function encodeList(bytes[] memory self) internal pure returns (bytes memory) { bytes memory list = flatten(self); return concat(encodeLength(list.length, 192), list); } /** * @dev RLP encodes a string. * @param self The string to encode. * @return The RLP encoded string in bytes. */ function encodeString(string memory self) internal pure returns (bytes memory) { return encodeBytes(bytes(self)); } /** * @dev RLP encodes an address. * @param self The address to encode. * @return The RLP encoded address in bytes. */ function encodeAddress(address self) internal pure returns (bytes memory) { bytes memory inputBytes; assembly { let m := mload(0x40) mstore(add(m, 20), xor(0x140000000000000000000000000000000000000000, self)) mstore(0x40, add(m, 52)) inputBytes := m } return encodeBytes(inputBytes); } /** * @dev RLP encodes a uint. * @param self The uint to encode. * @return The RLP encoded uint in bytes. */ function encodeUint(uint self) internal pure returns (bytes memory) { return encodeBytes(toBinary(self)); } /** * @dev RLP encodes an int. * @param self The int to encode. * @return The RLP encoded int in bytes. */ function encodeInt(int self) internal pure returns (bytes memory) { return encodeUint(uint(self)); } /** * @dev RLP encodes a bool. * @param self The bool to encode. * @return The RLP encoded bool in bytes. */ function encodeBool(bool self) internal pure returns (bytes memory) { bytes memory encoded = new bytes(1); encoded[0] = (self ? bytes1(0x01) : bytes1(0x80)); return encoded; } /* * Private functions */ /** * @dev Encode the first byte, followed by the `len` in binary form if `length` is more than 55. * @param len The length of the string or the payload. * @param offset 128 if item is string, 192 if item is list. * @return RLP encoded bytes. */ function encodeLength(uint len, uint offset) private pure returns (bytes memory) { bytes memory encoded; if (len < 56) { encoded = new bytes(1); encoded[0] = bytes32(len + offset)[31]; } else { uint lenLen; uint i = 1; while (len / i != 0) { lenLen++; i *= 256; } encoded = new bytes(lenLen + 1); encoded[0] = bytes32(lenLen + offset + 55)[31]; for(i = 1; i <= lenLen; i++) { encoded[i] = bytes32((len / (256**(lenLen-i))) % 256)[31]; } } return encoded; } /** * @dev Encode integer in big endian binary form with no leading zeroes. * @notice TODO: This should be optimized with assembly to save gas costs. * @param _x The integer to encode. * @return RLP encoded bytes. */ function toBinary(uint _x) private pure returns (bytes memory) { bytes memory b = new bytes(32); assembly { mstore(add(b, 32), _x) } uint i; for (i = 0; i < 32; i++) { if (b[i] != 0) { break; } } bytes memory res = new bytes(32 - i); for (uint j = 0; j < res.length; j++) { res[j] = b[i++]; } return res; } /** * @dev Copies a piece of memory to another location. * @notice From: https://github.com/Arachnid/solidity-stringutils/blob/master/src/strings.sol. * @param _dest Destination location. * @param _src Source location. * @param _len Length of memory to copy. */ function memcpy(uint _dest, uint _src, uint _len) private pure { uint dest = _dest; uint src = _src; uint len = _len; for(; len >= 32; len -= 32) { assembly { mstore(dest, mload(src)) } dest += 32; src += 32; } uint mask = 256 ** (32 - len) - 1; assembly { let srcpart := and(mload(src), not(mask)) let destpart := and(mload(dest), mask) mstore(dest, or(destpart, srcpart)) } } /** * @dev Flattens a list of byte strings into one byte string. * @notice From: https://github.com/sammayo/solidity-rlp-encoder/blob/master/RLPEncode.sol. * @param _list List of byte strings to flatten. * @return The flattened byte string. */ function flatten(bytes[] memory _list) private pure returns (bytes memory) { if (_list.length == 0) { return new bytes(0); } uint len; uint i; for (i = 0; i < _list.length; i++) { len += _list[i].length; } bytes memory flattened = new bytes(len); uint flattenedPtr; assembly { flattenedPtr := add(flattened, 0x20) } for(i = 0; i < _list.length; i++) { bytes memory item = _list[i]; uint listPtr; assembly { listPtr := add(item, 0x20)} memcpy(flattenedPtr, listPtr, item.length); flattenedPtr += _list[i].length; } return flattened; } /** * @dev Concatenates two bytes. * @notice From: https://github.com/GNSPS/solidity-bytes-utils/blob/master/contracts/BytesLib.sol. * @param _preBytes First byte string. * @param _postBytes Second byte string. * @return Both byte string combined. */ function concat(bytes memory _preBytes, bytes memory _postBytes) private pure returns (bytes memory) { bytes memory tempBytes; assembly { tempBytes := mload(0x40) let length := mload(_preBytes) mstore(tempBytes, length) let mc := add(tempBytes, 0x20) let end := add(mc, length) for { let cc := add(_preBytes, 0x20) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } length := mload(_postBytes) mstore(tempBytes, add(length, mload(tempBytes))) mc := end end := add(mc, length) for { let cc := add(_postBytes, 0x20) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } mstore(0x40, and( add(add(end, iszero(add(length, mload(_preBytes)))), 31), not(31) )) } return tempBytes; } } contract Governable is Initializable { address public governor; event GovernorshipTransferred(address indexed previousGovernor, address indexed newGovernor); /** * @dev Contract initializer. * called once by the factory at time of deployment */ function __Governable_init_unchained(address governor_) virtual public initializer { governor = governor_; emit GovernorshipTransferred(address(0), governor); } modifier governance() { require(msg.sender == governor); _; } /** * @dev Allows the current governor to relinquish control of the contract. * @notice Renouncing to governorship will leave the contract without an governor. * It will not be possible to call the functions with the `governance` * modifier anymore. */ function renounceGovernorship() public governance { emit GovernorshipTransferred(governor, address(0)); governor = address(0); } /** * @dev Allows the current governor to transfer control of the contract to a newGovernor. * @param newGovernor The address to transfer governorship to. */ function transferGovernorship(address newGovernor) public governance { _transferGovernorship(newGovernor); } /** * @dev Transfers control of the contract to a newGovernor. * @param newGovernor The address to transfer governorship to. */ function _transferGovernorship(address newGovernor) internal { require(newGovernor != address(0)); emit GovernorshipTransferred(governor, newGovernor); governor = newGovernor; } } contract ConfigurableBase { mapping (bytes32 => uint) internal config; function getConfig(bytes32 key) public view returns (uint) { return config[key]; } function getConfigI(bytes32 key, uint index) public view returns (uint) { return config[bytes32(uint(key) ^ index)]; } function getConfigA(bytes32 key, address addr) public view returns (uint) { return config[bytes32(uint(key) ^ uint(addr))]; } function _setConfig(bytes32 key, uint value) internal { if(config[key] != value) config[key] = value; } function _setConfig(bytes32 key, uint index, uint value) internal { _setConfig(bytes32(uint(key) ^ index), value); } function _setConfig(bytes32 key, address addr, uint value) internal { _setConfig(bytes32(uint(key) ^ uint(addr)), value); } } contract Configurable is Governable, ConfigurableBase { function setConfig(bytes32 key, uint value) external governance { _setConfig(key, value); } function setConfigI(bytes32 key, uint index, uint value) external governance { _setConfig(bytes32(uint(key) ^ index), value); } function setConfigA(bytes32 key, address addr, uint value) public governance { _setConfig(bytes32(uint(key) ^ uint(addr)), value); } } // Inheritancea interface IStakingRewards { // Views function lastTimeRewardApplicable() external view returns (uint256); function rewardPerToken() external view returns (uint256); function rewards(address account) external view returns (uint256); function earned(address account) external view returns (uint256); function getRewardForDuration() external view returns (uint256); function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); // Mutative function stake(uint256 amount) external; function withdraw(uint256 amount) external; function getReward() external; function exit() external; } abstract contract RewardsDistributionRecipient { address public rewardsDistribution; function notifyRewardAmount(uint256 reward) virtual external; modifier onlyRewardsDistribution() { require(msg.sender == rewardsDistribution, "Caller is not RewardsDistribution contract"); _; } } contract StakingRewards is IStakingRewards, RewardsDistributionRecipient, ReentrancyGuardUpgradeSafe { using SafeMath for uint256; using SafeERC20 for IERC20; /* ========== STATE VARIABLES ========== */ IERC20 public rewardsToken; IERC20 public stakingToken; uint256 public periodFinish = 0; uint256 public rewardRate = 0; // obsoleted uint256 public rewardsDuration = 60 days; uint256 public lastUpdateTime; uint256 public rewardPerTokenStored; mapping(address => uint256) public userRewardPerTokenPaid; mapping(address => uint256) override public rewards; uint256 internal _totalSupply; mapping(address => uint256) internal _balances; /* ========== CONSTRUCTOR ========== */ //constructor( function __StakingRewards_init( address _rewardsDistribution, address _rewardsToken, address _stakingToken ) public initializer { __ReentrancyGuard_init_unchained(); __StakingRewards_init_unchained(_rewardsDistribution, _rewardsToken, _stakingToken); } function __StakingRewards_init_unchained(address _rewardsDistribution, address _rewardsToken, address _stakingToken) public initializer { rewardsToken = IERC20(_rewardsToken); stakingToken = IERC20(_stakingToken); rewardsDistribution = _rewardsDistribution; } /* ========== VIEWS ========== */ function totalSupply() virtual override public view returns (uint256) { return _totalSupply; } function balanceOf(address account) virtual override public view returns (uint256) { return _balances[account]; } function lastTimeRewardApplicable() override public view returns (uint256) { return Math.min(block.timestamp, periodFinish); } function rewardPerToken() virtual override public view returns (uint256) { if (_totalSupply == 0) { return rewardPerTokenStored; } return rewardPerTokenStored.add( lastTimeRewardApplicable().sub(lastUpdateTime).mul(rewardRate).mul(1e18).div(_totalSupply) ); } function earned(address account) virtual override public view returns (uint256) { return _balances[account].mul(rewardPerToken().sub(userRewardPerTokenPaid[account])).div(1e18).add(rewards[account]); } function getRewardForDuration() virtual override external view returns (uint256) { return rewardRate.mul(rewardsDuration); } /* ========== MUTATIVE FUNCTIONS ========== */ function stakeWithPermit(uint256 amount, uint deadline, uint8 v, bytes32 r, bytes32 s) virtual public nonReentrant updateReward(msg.sender) { require(amount > 0, "Cannot stake 0"); _totalSupply = _totalSupply.add(amount); _balances[msg.sender] = _balances[msg.sender].add(amount); // permit IPermit(address(stakingToken)).permit(msg.sender, address(this), amount, deadline, v, r, s); stakingToken.safeTransferFrom(msg.sender, address(this), amount); emit Staked(msg.sender, amount); } function stake(uint256 amount) virtual override public nonReentrant updateReward(msg.sender) { require(amount > 0, "Cannot stake 0"); _totalSupply = _totalSupply.add(amount); _balances[msg.sender] = _balances[msg.sender].add(amount); stakingToken.safeTransferFrom(msg.sender, address(this), amount); emit Staked(msg.sender, amount); } function withdraw(uint256 amount) virtual override public nonReentrant updateReward(msg.sender) { require(amount > 0, "Cannot withdraw 0"); _totalSupply = _totalSupply.sub(amount); _balances[msg.sender] = _balances[msg.sender].sub(amount); stakingToken.safeTransfer(msg.sender, amount); emit Withdrawn(msg.sender, amount); } function getReward() virtual override public nonReentrant updateReward(msg.sender) { uint256 reward = rewards[msg.sender]; if (reward > 0) { rewards[msg.sender] = 0; rewardsToken.safeTransfer(msg.sender, reward); emit RewardPaid(msg.sender, reward); } } function exit() virtual override public { withdraw(_balances[msg.sender]); getReward(); } /* ========== RESTRICTED FUNCTIONS ========== */ function notifyRewardAmount(uint256 reward) override external onlyRewardsDistribution updateReward(address(0)) { if (block.timestamp >= periodFinish) { rewardRate = reward.div(rewardsDuration); } else { uint256 remaining = periodFinish.sub(block.timestamp); uint256 leftover = remaining.mul(rewardRate); rewardRate = reward.add(leftover).div(rewardsDuration); } // Ensure the provided reward amount is not more than the balance in the contract. // This keeps the reward rate in the right range, preventing overflows due to // very high values of rewardRate in the earned and rewardsPerToken functions; // Reward + leftover must be less than 2^256 / 10^18 to avoid overflow. uint balance = rewardsToken.balanceOf(address(this)); require(rewardRate <= balance.div(rewardsDuration), "Provided reward too high"); lastUpdateTime = block.timestamp; periodFinish = block.timestamp.add(rewardsDuration); emit RewardAdded(reward); } /* ========== MODIFIERS ========== */ modifier updateReward(address account) virtual { rewardPerTokenStored = rewardPerToken(); lastUpdateTime = lastTimeRewardApplicable(); if (account != address(0)) { rewards[account] = earned(account); userRewardPerTokenPaid[account] = rewardPerTokenStored; } _; } /* ========== EVENTS ========== */ event RewardAdded(uint256 reward); event Staked(address indexed user, uint256 amount); event Withdrawn(address indexed user, uint256 amount); event RewardPaid(address indexed user, uint256 reward); } interface IPermit { function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; } contract Constants { bytes32 internal constant _TokenMapped_ = 'TokenMapped'; bytes32 internal constant _MappableToken_ = 'MappableToken'; bytes32 internal constant _MappingToken_ = 'MappingToken'; bytes32 internal constant _fee_ = 'fee'; bytes32 internal constant _feeCreate_ = 'feeCreate'; bytes32 internal constant _feeRegister_ = 'feeRegister'; bytes32 internal constant _feeTo_ = 'feeTo'; bytes32 internal constant _onlyDeployer_ = 'onlyDeployer'; bytes32 internal constant _minSignatures_ = 'minSignatures'; bytes32 internal constant _initQuotaRatio_ = 'initQuotaRatio'; bytes32 internal constant _autoQuotaRatio_ = 'autoQuotaRatio'; bytes32 internal constant _autoQuotaPeriod_ = 'autoQuotaPeriod'; //bytes32 internal constant _uniswapRounter_ = 'uniswapRounter'; function _chainId() internal pure returns (uint id) { assembly { id := chainid() } } } struct Signature { address signatory; uint8 v; bytes32 r; bytes32 s; } abstract contract MappingBase is ContextUpgradeSafe, Constants { using SafeMath for uint; bytes32 public constant RECEIVE_TYPEHASH = keccak256("Receive(uint256 fromChainId,address to,uint256 nonce,uint256 volume,address signatory)"); bytes32 public constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)"); bytes32 internal _DOMAIN_SEPARATOR; function DOMAIN_SEPARATOR() virtual public view returns (bytes32) { return _DOMAIN_SEPARATOR; } address public factory; uint256 public mainChainId; address public token; address public deployer; mapping (address => uint) internal _authQuotas; // signatory => quota mapping (uint => mapping (address => uint)) public sentCount; // toChainId => to => sentCount mapping (uint => mapping (address => mapping (uint => uint))) public sent; // toChainId => to => nonce => volume mapping (uint => mapping (address => mapping (uint => uint))) public received; // fromChainId => to => nonce => volume mapping (address => uint) public lasttimeUpdateQuotaOf; // signatory => lasttime uint public autoQuotaRatio; uint public autoQuotaPeriod; function setAutoQuota(uint ratio, uint period) virtual external onlyFactory { autoQuotaRatio = ratio; autoQuotaPeriod = period; } modifier onlyFactory { require(msg.sender == factory, 'Only called by Factory'); _; } modifier updateAutoQuota(address signatory) virtual { uint quota = authQuotaOf(signatory); if(_authQuotas[signatory] != quota) { _authQuotas[signatory] = quota; lasttimeUpdateQuotaOf[signatory] = now; } _; } function authQuotaOf(address signatory) virtual public view returns (uint quota) { quota = _authQuotas[signatory]; uint ratio = autoQuotaRatio != 0 ? autoQuotaRatio : Factory(factory).getConfig(_autoQuotaRatio_); uint period = autoQuotaPeriod != 0 ? autoQuotaPeriod : Factory(factory).getConfig(_autoQuotaPeriod_); if(ratio == 0 || period == 0 || period == uint(-1)) return quota; uint quotaCap = cap().mul(ratio).div(1e18); uint delta = quotaCap.mul(now.sub(lasttimeUpdateQuotaOf[signatory])).div(period); return Math.max(quota, Math.min(quotaCap, quota.add(delta))); } function cap() public view virtual returns (uint); function increaseAuthQuotas(address[] memory signatories, uint[] memory increments) virtual external returns (uint[] memory quotas) { require(signatories.length == increments.length, 'two array lenth not equal'); quotas = new uint[](signatories.length); for(uint i=0; i<signatories.length; i++) quotas[i] = increaseAuthQuota(signatories[i], increments[i]); } function increaseAuthQuota(address signatory, uint increment) virtual public updateAutoQuota(signatory) onlyFactory returns (uint quota) { quota = _authQuotas[signatory].add(increment); _authQuotas[signatory] = quota; emit IncreaseAuthQuota(signatory, increment, quota); } event IncreaseAuthQuota(address indexed signatory, uint increment, uint quota); function decreaseAuthQuotas(address[] memory signatories, uint[] memory decrements) virtual external returns (uint[] memory quotas) { require(signatories.length == decrements.length, 'two array lenth not equal'); quotas = new uint[](signatories.length); for(uint i=0; i<signatories.length; i++) quotas[i] = decreaseAuthQuota(signatories[i], decrements[i]); } function decreaseAuthQuota(address signatory, uint decrement) virtual public onlyFactory returns (uint quota) { quota = authQuotaOf(signatory); if(quota < decrement) decrement = quota; return _decreaseAuthQuota(signatory, decrement); } function _decreaseAuthQuota(address signatory, uint decrement) virtual internal updateAutoQuota(signatory) returns (uint quota) { quota = _authQuotas[signatory].sub(decrement); _authQuotas[signatory] = quota; emit DecreaseAuthQuota(signatory, decrement, quota); } event DecreaseAuthQuota(address indexed signatory, uint decrement, uint quota); function needApprove() virtual public pure returns (bool); function send(uint toChainId, address to, uint volume) virtual external payable returns (uint nonce) { return sendFrom(_msgSender(), toChainId, to, volume); } function sendFrom(address from, uint toChainId, address to, uint volume) virtual public payable returns (uint nonce) { _chargeFee(); _sendFrom(from, volume); nonce = sentCount[toChainId][to]++; sent[toChainId][to][nonce] = volume; emit Send(from, toChainId, to, nonce, volume); } event Send(address indexed from, uint indexed toChainId, address indexed to, uint nonce, uint volume); function _sendFrom(address from, uint volume) virtual internal; function receive(uint256 fromChainId, address to, uint256 nonce, uint256 volume, Signature[] memory signatures) virtual external payable { _chargeFee(); require(received[fromChainId][to][nonce] == 0, 'withdrawn already'); uint N = signatures.length; require(N >= Factory(factory).getConfig(_minSignatures_), 'too few signatures'); for(uint i=0; i<N; i++) { for(uint j=0; j<i; j++) require(signatures[i].signatory != signatures[j].signatory, 'repetitive signatory'); bytes32 structHash = keccak256(abi.encode(RECEIVE_TYPEHASH, fromChainId, to, nonce, volume, signatures[i].signatory)); bytes32 digest = keccak256(abi.encodePacked("\x19\x01", _DOMAIN_SEPARATOR, structHash)); address signatory = ecrecover(digest, signatures[i].v, signatures[i].r, signatures[i].s); require(signatory != address(0), "invalid signature"); require(signatory == signatures[i].signatory, "unauthorized"); _decreaseAuthQuota(signatures[i].signatory, volume); emit Authorize(fromChainId, to, nonce, volume, signatory); } received[fromChainId][to][nonce] = volume; _receive(to, volume); emit Receive(fromChainId, to, nonce, volume); } event Receive(uint256 indexed fromChainId, address indexed to, uint256 indexed nonce, uint256 volume); event Authorize(uint256 fromChainId, address indexed to, uint256 indexed nonce, uint256 volume, address indexed signatory); function _receive(address to, uint256 volume) virtual internal; function _chargeFee() virtual internal { require(msg.value >= Math.min(Factory(factory).getConfig(_fee_), 0.1 ether), 'fee is too low'); address payable feeTo = address(Factory(factory).getConfig(_feeTo_)); if(feeTo == address(0)) feeTo = address(uint160(factory)); feeTo.transfer(msg.value); emit ChargeFee(_msgSender(), feeTo, msg.value); } event ChargeFee(address indexed from, address indexed to, uint value); uint256[47] private __gap; } contract TokenMapped is MappingBase { using SafeERC20 for IERC20; function __TokenMapped_init(address factory_, address token_) external initializer { __Context_init_unchained(); __TokenMapped_init_unchained(factory_, token_); } function __TokenMapped_init_unchained(address factory_, address token_) public initializer { factory = factory_; mainChainId = _chainId(); token = token_; deployer = address(0); _DOMAIN_SEPARATOR = keccak256(abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(ERC20UpgradeSafe(token).name())), _chainId(), address(this))); } function cap() virtual override public view returns (uint) { return IERC20(token).totalSupply(); } function totalMapped() virtual public view returns (uint) { return IERC20(token).balanceOf(address(this)); } function needApprove() virtual override public pure returns (bool) { return true; } function _sendFrom(address from, uint volume) virtual override internal { IERC20(token).safeTransferFrom(from, address(this), volume); } function _receive(address to, uint256 volume) virtual override internal { IERC20(token).safeTransfer(to, volume); } uint256[50] private __gap; } /* contract TokenMapped2 is TokenMapped, StakingRewards, ConfigurableBase { modifier governance { require(_msgSender() == MappingTokenFactory(factory).governor()); _; } function setConfig(bytes32 key, uint value) external governance { _setConfig(key, value); } function setConfigI(bytes32 key, uint index, uint value) external governance { _setConfig(bytes32(uint(key) ^ index), value); } function setConfigA(bytes32 key, address addr, uint value) public governance { _setConfig(bytes32(uint(key) ^ uint(addr)), value); } function rewardDelta() public view returns (uint amt) { if(begin == 0 || begin >= now || lastUpdateTime >= now) return 0; amt = rewardsToken.allowance(rewardsDistribution, address(this)).sub0(rewards[address(0)]); // calc rewardDelta in period if(lep == 3) { // power uint y = period.mul(1 ether).div(lastUpdateTime.add(rewardsDuration).sub(begin)); uint amt1 = amt.mul(1 ether).div(y); uint amt2 = amt1.mul(period).div(now.add(rewardsDuration).sub(begin)); amt = amt.sub(amt2); } else if(lep == 2) { // exponential if(now.sub(lastUpdateTime) < rewardsDuration) amt = amt.mul(now.sub(lastUpdateTime)).div(rewardsDuration); }else if(now < periodFinish) // linear amt = amt.mul(now.sub(lastUpdateTime)).div(periodFinish.sub(lastUpdateTime)); else if(lastUpdateTime >= periodFinish) amt = 0; } function rewardPerToken() virtual override public view returns (uint256) { if (_totalSupply == 0) { return rewardPerTokenStored; } return rewardPerTokenStored.add( rewardDelta().mul(1e18).div(_totalSupply) ); } modifier updateReward(address account) virtual override { (uint delta, uint d) = (rewardDelta(), 0); rewardPerTokenStored = rewardPerToken(); lastUpdateTime = now; if (account != address(0)) { rewards[account] = earned(account); userRewardPerTokenPaid[account] = rewardPerTokenStored; } address addr = address(config[_ecoAddr_]); uint ratio = config[_ecoRatio_]; if(addr != address(0) && ratio != 0) { d = delta.mul(ratio).div(1 ether); rewards[addr] = rewards[addr].add(d); } rewards[address(0)] = rewards[address(0)].add(delta).add(d); _; } function getReward() virtual override public { getReward(msg.sender); } function getReward(address payable acct) virtual public nonReentrant updateReward(acct) { require(acct != address(0), 'invalid address'); require(getConfig(_blocklist_, acct) == 0, 'In blocklist'); bool isContract = acct.isContract(); require(!isContract || config[_allowContract_] != 0 || getConfig(_allowlist_, acct) != 0, 'No allowContract'); uint256 reward = rewards[acct]; if (reward > 0) { paid[acct] = paid[acct].add(reward); paid[address(0)] = paid[address(0)].add(reward); rewards[acct] = 0; rewards[address(0)] = rewards[address(0)].sub0(reward); rewardsToken.safeTransferFrom(rewardsDistribution, acct, reward); emit RewardPaid(acct, reward); } } function getRewardForDuration() override external view returns (uint256) { return rewardsToken.allowance(rewardsDistribution, address(this)).sub0(rewards[address(0)]); } } */ abstract contract Permit { // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9; function DOMAIN_SEPARATOR() virtual public view returns (bytes32); mapping (address => uint) public nonces; function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external { require(deadline >= block.timestamp, 'permit EXPIRED'); bytes32 digest = keccak256( abi.encodePacked( '\x19\x01', DOMAIN_SEPARATOR(), keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline)) ) ); address recoveredAddress = ecrecover(digest, v, r, s); require(recoveredAddress != address(0) && recoveredAddress == owner, 'permit INVALID_SIGNATURE'); _approve(owner, spender, value); } function _approve(address owner, address spender, uint256 amount) internal virtual; uint256[50] private __gap; } contract MappableToken is Permit, ERC20UpgradeSafe, MappingBase { function __MappableToken_init(address factory_, address deployer_, string memory name_, string memory symbol_, uint8 decimals_, uint256 totalSupply_) external initializer { __Context_init_unchained(); __ERC20_init_unchained(name_, symbol_); _setupDecimals(decimals_); _mint(deployer_, totalSupply_); __MappableToken_init_unchained(factory_, deployer_); } function __MappableToken_init_unchained(address factory_, address deployer_) public initializer { factory = factory_; mainChainId = _chainId(); token = address(0); deployer = deployer_; _DOMAIN_SEPARATOR = keccak256(abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name())), _chainId(), address(this))); } function DOMAIN_SEPARATOR() virtual override(Permit, MappingBase) public view returns (bytes32) { return MappingBase.DOMAIN_SEPARATOR(); } function cap() virtual override public view returns (uint) { return totalSupply(); } function totalMapped() virtual public view returns (uint) { return balanceOf(address(this)); } function needApprove() virtual override public pure returns (bool) { return false; } function _approve(address owner, address spender, uint256 amount) virtual override(Permit, ERC20UpgradeSafe) internal { return ERC20UpgradeSafe._approve(owner, spender, amount); } function _sendFrom(address from, uint volume) virtual override internal { transferFrom(from, address(this), volume); } function _receive(address to, uint256 volume) virtual override internal { _transfer(address(this), to, volume); } uint256[50] private __gap; } contract MappingToken is Permit, ERC20CappedUpgradeSafe, MappingBase { function __MappingToken_init(address factory_, uint mainChainId_, address token_, address deployer_, string memory name_, string memory symbol_, uint8 decimals_, uint cap_) external initializer { __Context_init_unchained(); __ERC20_init_unchained(name_, symbol_); _setupDecimals(decimals_); __ERC20Capped_init_unchained(cap_); __MappingToken_init_unchained(factory_, mainChainId_, token_, deployer_); } function __MappingToken_init_unchained(address factory_, uint mainChainId_, address token_, address deployer_) public initializer { factory = factory_; mainChainId = mainChainId_; token = token_; deployer = (token_ == address(0)) ? deployer_ : address(0); _DOMAIN_SEPARATOR = keccak256(abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name())), _chainId(), address(this))); } function DOMAIN_SEPARATOR() virtual override(Permit, MappingBase) public view returns (bytes32) { return MappingBase.DOMAIN_SEPARATOR(); } function cap() virtual override(ERC20CappedUpgradeSafe, MappingBase) public view returns (uint) { return ERC20CappedUpgradeSafe.cap(); } function needApprove() virtual override public pure returns (bool) { return false; } function _approve(address owner, address spender, uint256 amount) virtual override(Permit, ERC20UpgradeSafe) internal { return ERC20UpgradeSafe._approve(owner, spender, amount); } function _sendFrom(address from, uint volume) virtual override internal { _burn(from, volume); if(from != _msgSender() && allowance(from, _msgSender()) != uint(-1)) _approve(from, _msgSender(), allowance(from, _msgSender()).sub(volume, "ERC20: transfer volume exceeds allowance")); } function _receive(address to, uint256 volume) virtual override internal { _mint(to, volume); } uint256[50] private __gap; } contract MappingTokenProxy is ProductProxy, Constants { constructor(address factory_, uint mainChainId_, address token_, address deployer_, string memory name_, string memory symbol_, uint8 decimals_, uint cap_) public { //require(_factory() == address(0)); assert(FACTORY_SLOT == bytes32(uint256(keccak256('eip1967.proxy.factory')) - 1)); assert(NAME_SLOT == bytes32(uint256(keccak256('eip1967.proxy.name')) - 1)); _setFactory(factory_); _setName(_MappingToken_); (bool success,) = _implementation().delegatecall(abi.encodeWithSignature('__MappingToken_init(address,uint256,address,address,string,string,uint8,uint256)', factory_, mainChainId_, token_, deployer_, name_, symbol_, decimals_, cap_)); require(success); } } contract Factory is ContextUpgradeSafe, Configurable, Constants { using SafeERC20 for IERC20; using SafeMath for uint; bytes32 public constant REGISTER_TYPEHASH = keccak256("RegisterMapping(uint mainChainId,address token,uint[] chainIds,address[] mappingTokenMappeds,address signatory)"); bytes32 public constant CREATE_TYPEHASH = keccak256("CreateMappingToken(address deployer,uint mainChainId,address token,string name,string symbol,uint8 decimals,uint cap,address signatory)"); bytes32 public constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)"); bytes32 public DOMAIN_SEPARATOR; mapping (bytes32 => address) public productImplementations; mapping (address => address) public tokenMappeds; // token => tokenMapped mapping (address => address) public mappableTokens; // deployer => mappableTokens mapping (uint256 => mapping (address => address)) public mappingTokens; // mainChainId => token or deployer => mappableTokens mapping (address => bool) public authorties; // only on ethereum mainnet mapping (address => uint) public authCountOf; // signatory => count mapping (address => uint256) internal _mainChainIdTokens; // mappingToken => mainChainId+token mapping (address => mapping (uint => address)) public mappingTokenMappeds; // token => chainId => mappingToken or tokenMapped uint[] public supportChainIds; mapping (string => uint256) internal _certifiedTokens; // symbol => mainChainId+token string[] public certifiedSymbols; address[] public signatories; function __MappingTokenFactory_init(address _governor, address _implTokenMapped, address _implMappableToken, address _implMappingToken, address _feeTo) external initializer { __Governable_init_unchained(_governor); __MappingTokenFactory_init_unchained(_implTokenMapped, _implMappableToken, _implMappingToken, _feeTo); } function __MappingTokenFactory_init_unchained(address _implTokenMapped, address _implMappableToken, address _implMappingToken, address _feeTo) public governance { config[_fee_] = 0.005 ether; config[_feeCreate_] = 0.100 ether; config[_feeRegister_] = 0.200 ether; config[_feeTo_] = uint(_feeTo); config[_onlyDeployer_] = 1; config[_minSignatures_] = 3; config[_initQuotaRatio_] = 0.100 ether; // 10% config[_autoQuotaRatio_] = 0.010 ether; // 1% config[_autoQuotaPeriod_] = 1 days; //config[_uniswapRounter_] = uint(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D); DOMAIN_SEPARATOR = keccak256(abi.encode(DOMAIN_TYPEHASH, keccak256(bytes('MappingTokenFactory')), _chainId(), address(this))); upgradeProductImplementationsTo_(_implTokenMapped, _implMappableToken, _implMappingToken); emit ProductProxyCodeHash(keccak256(type(InitializableProductProxy).creationCode)); } event ProductProxyCodeHash(bytes32 codeHash); function upgradeProductImplementationsTo_(address _implTokenMapped, address _implMappableToken, address _implMappingToken) public governance { productImplementations[_TokenMapped_] = _implTokenMapped; productImplementations[_MappableToken_] = _implMappableToken; productImplementations[_MappingToken_] = _implMappingToken; } function setSignatories(address[] calldata signatories_) virtual external governance { signatories = signatories_; emit SetSignatories(signatories_); } event SetSignatories(address[] signatories_); function setAuthorty_(address authorty, bool enable) virtual external governance { authorties[authorty] = enable; emit SetAuthorty(authorty, enable); } event SetAuthorty(address indexed authorty, bool indexed enable); function setAutoQuota(address mappingTokenMapped, uint ratio, uint period) virtual external governance { if(mappingTokenMapped == address(0)) { config[_autoQuotaRatio_] = ratio; config[_autoQuotaPeriod_] = period; } else MappingBase(mappingTokenMapped).setAutoQuota(ratio, period); } modifier onlyAuthorty { require(authorties[_msgSender()], 'only authorty'); _; } function _initAuthQuotas(address mappingTokenMapped, uint cap) internal { uint quota = cap.mul(config[_initQuotaRatio_]).div(1e18); uint[] memory quotas = new uint[](signatories.length); for(uint i=0; i<quotas.length; i++) quotas[i] = quota; _increaseAuthQuotas(mappingTokenMapped, signatories, quotas); } function _increaseAuthQuotas(address mappingTokenMapped, address[] memory signatories_, uint[] memory increments) virtual internal returns (uint[] memory quotas) { quotas = MappingBase(mappingTokenMapped).increaseAuthQuotas(signatories_, increments); for(uint i=0; i<signatories_.length; i++) emit IncreaseAuthQuota(_msgSender(), mappingTokenMapped, signatories_[i], increments[i], quotas[i]); } function increaseAuthQuotas_(address mappingTokenMapped, uint[] memory increments) virtual external onlyAuthorty returns (uint[] memory quotas) { return _increaseAuthQuotas(mappingTokenMapped, signatories, increments); } function increaseAuthQuotas(address mappingTokenMapped, address[] memory signatories_, uint[] memory increments) virtual external onlyAuthorty returns (uint[] memory quotas) { return _increaseAuthQuotas(mappingTokenMapped, signatories_, increments); } function increaseAuthQuota(address mappingTokenMapped, address signatory, uint increment) virtual external onlyAuthorty returns (uint quota) { quota = MappingBase(mappingTokenMapped).increaseAuthQuota(signatory, increment); emit IncreaseAuthQuota(_msgSender(), mappingTokenMapped, signatory, increment, quota); } event IncreaseAuthQuota(address indexed authorty, address indexed mappingTokenMapped, address indexed signatory, uint increment, uint quota); function decreaseAuthQuotas_(address mappingTokenMapped, uint[] memory decrements) virtual external returns (uint[] memory quotas) { return decreaseAuthQuotas(mappingTokenMapped, signatories, decrements); } function decreaseAuthQuotas(address mappingTokenMapped, address[] memory signatories_, uint[] memory decrements) virtual public onlyAuthorty returns (uint[] memory quotas) { quotas = MappingBase(mappingTokenMapped).decreaseAuthQuotas(signatories_, decrements); for(uint i=0; i<signatories_.length; i++) emit DecreaseAuthQuota(_msgSender(), mappingTokenMapped, signatories_[i], decrements[i], quotas[i]); } function decreaseAuthQuota(address mappingTokenMapped, address signatory, uint decrement) virtual external onlyAuthorty returns (uint quota) { quota = MappingBase(mappingTokenMapped).decreaseAuthQuota(signatory, decrement); emit DecreaseAuthQuota(_msgSender(), mappingTokenMapped, signatory, decrement, quota); } event DecreaseAuthQuota(address indexed authorty, address indexed mappingTokenMapped, address indexed signatory, uint decrement, uint quota); function increaseAuthCounts_(uint[] memory increments) virtual external returns (uint[] memory counts) { return increaseAuthCounts(signatories, increments); } function increaseAuthCounts(address[] memory signatories_, uint[] memory increments) virtual public returns (uint[] memory counts) { require(signatories_.length == increments.length, 'two array lenth not equal'); counts = new uint[](signatories_.length); for(uint i=0; i<signatories_.length; i++) counts[i] = increaseAuthCount(signatories_[i], increments[i]); } function increaseAuthCount(address signatory, uint increment) virtual public onlyAuthorty returns (uint count) { count = authCountOf[signatory].add(increment); authCountOf[signatory] = count; emit IncreaseAuthQuota(_msgSender(), signatory, increment, count); } event IncreaseAuthQuota(address indexed authorty, address indexed signatory, uint increment, uint quota); function decreaseAuthCounts_(uint[] memory decrements) virtual external returns (uint[] memory counts) { return decreaseAuthCounts(signatories, decrements); } function decreaseAuthCounts(address[] memory signatories_, uint[] memory decrements) virtual public returns (uint[] memory counts) { require(signatories_.length == decrements.length, 'two array lenth not equal'); counts = new uint[](signatories_.length); for(uint i=0; i<signatories_.length; i++) counts[i] = decreaseAuthCount(signatories_[i], decrements[i]); } function decreaseAuthCount(address signatory, uint decrement) virtual public onlyAuthorty returns (uint count) { count = authCountOf[signatory]; if(count < decrement) decrement = count; return _decreaseAuthCount(signatory, decrement); } function _decreaseAuthCount(address signatory, uint decrement) virtual internal returns (uint count) { count = authCountOf[signatory].sub(decrement); authCountOf[signatory] = count; emit DecreaseAuthCount(_msgSender(), signatory, decrement, count); } event DecreaseAuthCount(address indexed authorty, address indexed signatory, uint decrement, uint count); function supportChainCount() public view returns (uint) { return supportChainIds.length; } function mainChainIdTokens(address mappingToken) virtual public view returns(uint mainChainId, address token) { uint256 chainIdToken = _mainChainIdTokens[mappingToken]; mainChainId = chainIdToken >> 160; token = address(chainIdToken); } function chainIdMappingTokenMappeds(address tokenOrMappingToken) virtual external view returns (uint[] memory chainIds, address[] memory mappingTokenMappeds_) { (, address token) = mainChainIdTokens(tokenOrMappingToken); if(token == address(0)) token = tokenOrMappingToken; uint N = 0; for(uint i=0; i<supportChainCount(); i++) if(mappingTokenMappeds[token][supportChainIds[i]] != address(0)) N++; chainIds = new uint[](N); mappingTokenMappeds_ = new address[](N); uint j = 0; for(uint i=0; i<supportChainCount(); i++) { uint chainId = supportChainIds[i]; address mappingTokenMapped = mappingTokenMappeds[token][chainId]; if(mappingTokenMapped != address(0)) { chainIds[j] = chainId; mappingTokenMappeds_[j] = mappingTokenMapped; j++; } } } function isSupportChainId(uint chainId) virtual public view returns (bool) { for(uint i=0; i<supportChainCount(); i++) if(supportChainIds[i] == chainId) return true; return false; } function registerSupportChainId_(uint chainId_) virtual external governance { require(_chainId() == 1 || _chainId() == 3, 'called only on ethereum mainnet'); require(!isSupportChainId(chainId_), 'support chainId already'); supportChainIds.push(chainId_); } function _registerMapping(uint mainChainId, address token, uint[] memory chainIds, address[] memory mappingTokenMappeds_) virtual internal { require(_chainId() == 1 || _chainId() == 3, 'called only on ethereum mainnet'); require(chainIds.length == mappingTokenMappeds_.length, 'two array lenth not equal'); require(isSupportChainId(mainChainId), 'Not support mainChainId'); for(uint i=0; i<chainIds.length; i++) { require(isSupportChainId(chainIds[i]), 'Not support chainId'); require(token == mappingTokenMappeds_[i] || mappingTokenMappeds_[i] == calcMapping(mainChainId, token) || _msgSender() == governor, 'invalid mappingTokenMapped address'); //require(_mainChainIdTokens[mappingTokenMappeds_[i]] == 0 || _mainChainIdTokens[mappingTokenMappeds_[i]] == (mainChainId << 160) | uint(token), 'mainChainIdTokens exist already'); //require(mappingTokenMappeds[token][chainIds[i]] == address(0), 'mappingTokenMappeds exist already'); //if(_mainChainIdTokens[mappingTokenMappeds_[i]] == 0) _mainChainIdTokens[mappingTokenMappeds_[i]] = (mainChainId << 160) | uint(token); mappingTokenMappeds[token][chainIds[i]] = mappingTokenMappeds_[i]; emit RegisterMapping(mainChainId, token, chainIds[i], mappingTokenMappeds_[i]); } } event RegisterMapping(uint mainChainId, address token, uint chainId, address mappingTokenMapped); function registerMapping_(uint mainChainId, address token, uint[] memory chainIds, address[] memory mappingTokenMappeds_) virtual external governance { _registerMapping(mainChainId, token, chainIds, mappingTokenMappeds_); } function registerMapping(uint mainChainId, address token, uint nonce, uint[] memory chainIds, address[] memory mappingTokenMappeds_, Signature[] memory signatures) virtual external payable { _chargeFee(config[_feeRegister_]); require(config[_onlyDeployer_] == 0 || token == calcContract(_msgSender(), nonce), 'only deployer'); uint N = signatures.length; require(N >= getConfig(_minSignatures_), 'too few signatures'); for(uint i=0; i<N; i++) { for(uint j=0; j<i; j++) require(signatures[i].signatory != signatures[j].signatory, 'repetitive signatory'); bytes32 structHash = keccak256(abi.encode(REGISTER_TYPEHASH, mainChainId, token, keccak256(abi.encodePacked(chainIds)), keccak256(abi.encodePacked(mappingTokenMappeds_)), signatures[i].signatory)); bytes32 digest = keccak256(abi.encodePacked("\x19\x01", DOMAIN_SEPARATOR, structHash)); address signatory = ecrecover(digest, signatures[i].v, signatures[i].r, signatures[i].s); require(signatory != address(0), "invalid signature"); require(signatory == signatures[i].signatory, "unauthorized"); _decreaseAuthCount(signatures[i].signatory, 1); emit AuthorizeRegister(mainChainId, token, signatory); } _registerMapping(mainChainId, token, chainIds, mappingTokenMappeds_); } event AuthorizeRegister(uint indexed mainChainId, address indexed token, address indexed signatory); function certifiedCount() external view returns (uint) { return certifiedSymbols.length; } function certifiedTokens(string memory symbol) public view returns (uint mainChainId, address token) { uint256 chainIdToken = _certifiedTokens[symbol]; mainChainId = chainIdToken >> 160; token = address(chainIdToken); } function allCertifiedTokens() external view returns (string[] memory symbols, uint[] memory chainIds, address[] memory tokens) { symbols = certifiedSymbols; uint N = certifiedSymbols.length; chainIds = new uint[](N); tokens = new address[](N); for(uint i=0; i<N; i++) (chainIds[i], tokens[i]) = certifiedTokens(certifiedSymbols[i]); } function registerCertified_(string memory symbol, uint mainChainId, address token) external governance { require(_chainId() == 1 || _chainId() == 3, 'called only on ethereum mainnet'); require(isSupportChainId(mainChainId), 'Not support mainChainId'); require(_certifiedTokens[symbol] == 0, 'Certified added already'); if(mainChainId == _chainId()) require(keccak256(bytes(symbol)) == keccak256(bytes(ERC20UpgradeSafe(token).symbol())), 'symbol different'); _certifiedTokens[symbol] = (mainChainId << 160) | uint(token); certifiedSymbols.push(symbol); emit RegisterCertified(symbol, mainChainId, token); } event RegisterCertified(string indexed symbol, uint indexed mainChainId, address indexed token); //function updateCertified_(string memory symbol, uint mainChainId, address token) external governance { // require(_chainId() == 1 || _chainId() == 3, 'called only on ethereum mainnet'); // require(isSupportChainId(mainChainId), 'Not support mainChainId'); // //require(_certifiedTokens[symbol] == 0, 'Certified added already'); // if(mainChainId == _chainId()) // require(keccak256(bytes(symbol)) == keccak256(bytes(ERC20UpgradeSafe(token).symbol())), 'symbol different'); // _certifiedTokens[symbol] = (mainChainId << 160) | uint(token); // //certifiedSymbols.push(symbol); // emit UpdateCertified(symbol, mainChainId, token); //} //event UpdateCertified(string indexed symbol, uint indexed mainChainId, address indexed token); function calcContract(address deployer, uint nonce) public pure returns (address) { bytes[] memory list = new bytes[](2); list[0] = RLPEncode.encodeAddress(deployer); list[1] = RLPEncode.encodeUint(nonce); return address(uint(keccak256(RLPEncode.encodeList(list)))); } // calculates the CREATE2 address for a pair without making any external calls function calcMapping(uint mainChainId, address tokenOrdeployer) public view returns (address) { return address(uint(keccak256(abi.encodePacked( hex'ff', address(this), keccak256(abi.encodePacked(mainChainId, tokenOrdeployer)), keccak256(type(InitializableProductProxy).creationCode) //hex'96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f' // init code hash )))); } function createTokenMapped(address token, uint nonce) external payable returns (address tokenMapped) { if(_msgSender() != governor) { _chargeFee(config[_feeCreate_]); require(config[_onlyDeployer_] == 0 || token == calcContract(_msgSender(), nonce), 'only deployer'); } require(tokenMappeds[token] == address(0), 'TokenMapped created already'); bytes32 salt = keccak256(abi.encodePacked(_chainId(), token)); bytes memory bytecode = type(InitializableProductProxy).creationCode; assembly { tokenMapped := create2(0, add(bytecode, 32), mload(bytecode), salt) } InitializableProductProxy(payable(tokenMapped)).__InitializableProductProxy_init(address(this), _TokenMapped_, abi.encodeWithSignature('__TokenMapped_init(address,address)', address(this), token)); tokenMappeds[token] = tokenMapped; _initAuthQuotas(tokenMapped, IERC20(token).totalSupply()); emit CreateTokenMapped(_msgSender(), token, tokenMapped); } event CreateTokenMapped(address indexed deployer, address indexed token, address indexed tokenMapped); function createMappableToken(string memory name, string memory symbol, uint8 decimals, uint totalSupply) external payable returns (address mappableToken) { if(_msgSender() != governor) _chargeFee(config[_feeCreate_]); require(mappableTokens[_msgSender()] == address(0), 'MappableToken created already'); bytes32 salt = keccak256(abi.encodePacked(_chainId(), _msgSender())); bytes memory bytecode = type(InitializableProductProxy).creationCode; assembly { mappableToken := create2(0, add(bytecode, 32), mload(bytecode), salt) } InitializableProductProxy(payable(mappableToken)).__InitializableProductProxy_init(address(this), _MappableToken_, abi.encodeWithSignature('__MappableToken_init(address,address,string,string,uint8,uint256)', address(this), _msgSender(), name, symbol, decimals, totalSupply)); mappableTokens[_msgSender()] = mappableToken; _initAuthQuotas(mappableToken, totalSupply); emit CreateMappableToken(_msgSender(), name, symbol, decimals, totalSupply, mappableToken); } event CreateMappableToken(address indexed deployer, string name, string symbol, uint8 decimals, uint totalSupply, address indexed mappableToken); function _createMappingToken(uint mainChainId, address token, address deployer, string memory name, string memory symbol, uint8 decimals, uint cap) internal returns (address mappingToken) { address tokenOrdeployer = (token == address(0)) ? deployer : token; require(mappingTokens[mainChainId][tokenOrdeployer] == address(0), 'MappingToken created already'); bytes32 salt = keccak256(abi.encodePacked(mainChainId, tokenOrdeployer)); bytes memory bytecode = type(InitializableProductProxy).creationCode; assembly { mappingToken := create2(0, add(bytecode, 32), mload(bytecode), salt) } InitializableProductProxy(payable(mappingToken)).__InitializableProductProxy_init(address(this), _MappingToken_, abi.encodeWithSignature('__MappingToken_init(address,uint256,address,address,string,string,uint8,uint256)', address(this), mainChainId, token, deployer, name, symbol, decimals, cap)); mappingTokens[mainChainId][tokenOrdeployer] = mappingToken; _initAuthQuotas(mappingToken, cap); emit CreateMappingToken(mainChainId, token, deployer, name, symbol, decimals, cap, mappingToken); } event CreateMappingToken(uint mainChainId, address indexed token, address indexed deployer, string name, string symbol, uint8 decimals, uint cap, address indexed mappingToken); function createMappingToken_(uint mainChainId, address token, address deployer, string memory name, string memory symbol, uint8 decimals, uint cap) public payable governance returns (address mappingToken) { return _createMappingToken(mainChainId, token, deployer, name, symbol, decimals, cap); } function createMappingToken(uint mainChainId, address token, uint nonce, string memory name, string memory symbol, uint8 decimals, uint cap, Signature[] memory signatures) public payable returns (address mappingToken) { _chargeFee(config[_feeCreate_]); require(token == address(0) || config[_onlyDeployer_] == 0 || token == calcContract(_msgSender(), nonce), 'only deployer'); require(signatures.length >= config[_minSignatures_], 'too few signatures'); for(uint i=0; i<signatures.length; i++) { for(uint j=0; j<i; j++) require(signatures[i].signatory != signatures[j].signatory, 'repetitive signatory'); bytes32 hash = keccak256(abi.encode(CREATE_TYPEHASH, _msgSender(), mainChainId, token, keccak256(bytes(name)), keccak256(bytes(symbol)), decimals, cap, signatures[i].signatory)); hash = keccak256(abi.encodePacked("\x19\x01", DOMAIN_SEPARATOR, hash)); address signatory = ecrecover(hash, signatures[i].v, signatures[i].r, signatures[i].s); require(signatory != address(0), "invalid signature"); require(signatory == signatures[i].signatory, "unauthorized"); _decreaseAuthCount(signatures[i].signatory, 1); emit AuthorizeCreate(mainChainId, token, _msgSender(), name, symbol, decimals, cap, signatory); } return _createMappingToken(mainChainId, token, _msgSender(), name, symbol, decimals, cap); } event AuthorizeCreate(uint mainChainId, address indexed token, address indexed deployer, string name, string symbol, uint8 decimals, uint cap, address indexed signatory); function _chargeFee(uint fee) virtual internal { require(msg.value >= Math.min(fee, 1 ether), 'fee is too low'); address payable feeTo = address(config[_feeTo_]); if(feeTo == address(0)) feeTo = address(uint160(address(this))); feeTo.transfer(msg.value); emit ChargeFee(_msgSender(), feeTo, msg.value); } event ChargeFee(address indexed from, address indexed to, uint value); uint256[49] private __gap; }
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":false,"internalType":"uint256","name":"fromChainId","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"volume","type":"uint256"},{"indexed":true,"internalType":"address","name":"signatory","type":"address"}],"name":"Authorize","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":"ChargeFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"signatory","type":"address"},{"indexed":false,"internalType":"uint256","name":"decrement","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"quota","type":"uint256"}],"name":"DecreaseAuthQuota","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"signatory","type":"address"},{"indexed":false,"internalType":"uint256","name":"increment","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"quota","type":"uint256"}],"name":"IncreaseAuthQuota","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromChainId","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"volume","type":"uint256"}],"name":"Receive","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"uint256","name":"toChainId","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"volume","type":"uint256"}],"name":"Send","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":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RECEIVE_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"factory_","type":"address"},{"internalType":"address","name":"deployer_","type":"address"},{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"uint8","name":"decimals_","type":"uint8"},{"internalType":"uint256","name":"totalSupply_","type":"uint256"}],"name":"__MappableToken_init","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"factory_","type":"address"},{"internalType":"address","name":"deployer_","type":"address"}],"name":"__MappableToken_init_unchained","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","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":"signatory","type":"address"}],"name":"authQuotaOf","outputs":[{"internalType":"uint256","name":"quota","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"autoQuotaPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"autoQuotaRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","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":[{"internalType":"address","name":"signatory","type":"address"},{"internalType":"uint256","name":"decrement","type":"uint256"}],"name":"decreaseAuthQuota","outputs":[{"internalType":"uint256","name":"quota","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"signatories","type":"address[]"},{"internalType":"uint256[]","name":"decrements","type":"uint256[]"}],"name":"decreaseAuthQuotas","outputs":[{"internalType":"uint256[]","name":"quotas","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deployer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","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":[{"internalType":"address","name":"signatory","type":"address"},{"internalType":"uint256","name":"increment","type":"uint256"}],"name":"increaseAuthQuota","outputs":[{"internalType":"uint256","name":"quota","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"signatories","type":"address[]"},{"internalType":"uint256[]","name":"increments","type":"uint256[]"}],"name":"increaseAuthQuotas","outputs":[{"internalType":"uint256[]","name":"quotas","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lasttimeUpdateQuotaOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mainChainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"needApprove","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"fromChainId","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"volume","type":"uint256"},{"components":[{"internalType":"address","name":"signatory","type":"address"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct Signature[]","name":"signatures","type":"tuple[]"}],"name":"receive","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"received","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"toChainId","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"volume","type":"uint256"}],"name":"send","outputs":[{"internalType":"uint256","name":"nonce","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"toChainId","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"volume","type":"uint256"}],"name":"sendFrom","outputs":[{"internalType":"uint256","name":"nonce","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"sent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"sentCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"ratio","type":"uint256"},{"internalType":"uint256","name":"period","type":"uint256"}],"name":"setAutoQuota","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalMapped","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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"}]
Contract Creation Code
608060405234801561001057600080fd5b50612d99806100206000396000f3fe6080604052600436106102465760003560e01c806370a0823111610139578063a653d60c116100b6578063dc51b6ac1161007a578063dc51b6ac14610638578063dd62ed3e1461064d578063df735d621461066d578063e6eeae721461068d578063fc0c546a146106ad578063fe57a691146106c257610246565b8063a653d60c146105ae578063a9059cbb146105c1578063c45a0155146105e1578063d505accf14610603578063d5f394881461062357610246565b806381b34f15116100fd57806381b34f1514610531578063829009341461054457806395d89b4114610559578063a25d7c861461056e578063a457c2d71461058e57610246565b806370a082311461049157806375986b50146104b15780637a4c7801146104d15780637a62f5c6146104f15780637ecebe001461051157610246565b806323b872dd116101c75780633644e5151161018b5780633644e5151461041257806337ee3a2a14610427578063395093511461043c5780635d3b5f801461045c5780636489aba51461047157610246565b806323b872dd146103935780632c4a952b146103b357806330adf81f146103c6578063313ce567146103db578063355274ea146103fd57610246565b806318160ddd1161020e57806318160ddd146103075780631e86c2ac1461031c57806320606b70146103495780632186ff4e1461035e57806322d205791461037e57610246565b806306fdde031461024b578063095ea7b3146102765780630c0f261e146102a35780630f45ad43146102d05780630fba758d146102e5575b600080fd5b34801561025757600080fd5b506102606106e2565b60405161026d9190612856565b60405180910390f35b34801561028257600080fd5b5061029661029136600461245b565b610778565b60405161026d9190612798565b3480156102af57600080fd5b506102c36102be3660046122b8565b610796565b60405161026d91906127a3565b3480156102dc57600080fd5b506102c36109ab565b3480156102f157600080fd5b506103056103003660046122d3565b6109b1565b005b34801561031357600080fd5b506102c3610af3565b34801561032857600080fd5b5061033c6103373660046124ca565b610af9565b60405161026d9190612754565b34801561035557600080fd5b506102c3610bc3565b34801561036a57600080fd5b506102c36103793660046125c7565b610be7565b34801561038a57600080fd5b506102c3610c0a565b34801561039f57600080fd5b506102966103ae3660046123af565b610c10565b6102c36103c1366004612485565b610d08565b3480156103d257600080fd5b506102c3610db4565b3480156103e757600080fd5b506103f0610dd8565b60405161026d9190612c86565b34801561040957600080fd5b506102c3610de1565b34801561041e57600080fd5b506102c3610df0565b34801561043357600080fd5b506102c3610dfa565b34801561044857600080fd5b5061029661045736600461245b565b610e00565b34801561046857600080fd5b50610296610e4e565b34801561047d57600080fd5b506102c361048c36600461245b565b610e53565b34801561049d57600080fd5b506102c36104ac3660046122b8565b610ea8565b3480156104bd57600080fd5b506102c36104cc3660046125c7565b610ec3565b3480156104dd57600080fd5b506103056104ec366004612704565b610ee6565b3480156104fd57600080fd5b506102c361050c36600461245b565b610f1b565b34801561051d57600080fd5b506102c361052c3660046122b8565b611022565b6102c361053f3660046125c7565b611034565b34801561055057600080fd5b506102c3611051565b34801561056557600080fd5b50610260611075565b34801561057a57600080fd5b5061033c6105893660046124ca565b6110d6565b34801561059a57600080fd5b506102966105a936600461245b565b611199565b6103056105bc3660046125fc565b611201565b3480156105cd57600080fd5b506102966105dc36600461245b565b611621565b3480156105ed57600080fd5b506105f6611635565b60405161026d9190612740565b34801561060f57600080fd5b5061030561061e3660046123ef565b611644565b34801561062f57600080fd5b506105f66117b7565b34801561064457600080fd5b506102c36117c6565b34801561065957600080fd5b506102c36106683660046122d3565b6117d1565b34801561067957600080fd5b50610305610688366004612307565b6117fc565b34801561069957600080fd5b506102c36106a83660046122b8565b6118b4565b3480156106b957600080fd5b506105f66118c6565b3480156106ce57600080fd5b506102c36106dd3660046125a4565b6118d5565b609b8054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561076e5780601f106107435761010080835404028352916020019161076e565b820191906000526020600020905b81548152906001019060200180831161075157829003601f168201915b5050505050905090565b600061078c6107856118f2565b84846118f6565b5060015b92915050565b6001600160a01b038116600090815260cf602052604081205460d45490919061084f5760cb54604051636dd5b69d60e01b81526001600160a01b0390911690636dd5b69d906107fa906d6175746f51756f7461526174696f60901b906004016127a3565b60206040518083038186803b15801561081257600080fd5b505afa158015610826573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061084a919061258c565b610853565b60d4545b9050600060d554600014156108f95760cb54604051636dd5b69d60e01b81526001600160a01b0390911690636dd5b69d906108a4906e185d5d1bd45d5bdd1854195c9a5bd9608a1b906004016127a3565b60206040518083038186803b1580156108bc57600080fd5b505afa1580156108d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f4919061258c565b6108fd565b60d5545b905081158061090a575080155b80610916575060001981145b156109225750506109a6565b6000610948670de0b6b3a76400006109428561093c610de1565b90611901565b9061193b565b6001600160a01b038616600090815260d36020526040812054919250906109819084906109429061097a90429061197d565b8590611901565b905061099f8561099a8461099583866119bf565b6119e4565b6119fa565b9450505050505b919050565b60cc5481565b603354610100900460ff16806109ca57506109ca611a0a565b806109d8575060335460ff16155b6109fd5760405162461bcd60e51b81526004016109f490612b03565b60405180910390fd5b603354610100900460ff16158015610a28576033805460ff1961ff0019909116610100171660011790555b60cb80546001600160a01b0319166001600160a01b038516179055610a4b611a10565b60cc5560cd80546001600160a01b031990811690915560ce80549091166001600160a01b0384161790557f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a866610a9e6106e2565b80519060200120610aad611a10565b30604051602001610ac194939291906127e0565b60408051601f19818403018152919052805160209091012060ca558015610aee576033805461ff00191690555b505050565b609a5490565b60608151835114610b1c5760405162461bcd60e51b81526004016109f490612b51565b825167ffffffffffffffff81118015610b3457600080fd5b50604051908082528060200260200182016040528015610b5e578160200160208202803683370190505b50905060005b8351811015610bbc57610b9d848281518110610b7c57fe5b6020026020010151848381518110610b9057fe5b6020026020010151610f1b565b828281518110610ba957fe5b6020908102919091010152600101610b64565b5092915050565b7f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b60d260209081526000938452604080852082529284528284209052825290205481565b60d45481565b6000610c1d848484611a14565b610c256118f2565b6001600160a01b0316846001600160a01b031614158015610c8957506001600160a01b038416600090815260996020526040812060001991610c656118f2565b6001600160a01b03166001600160a01b031681526020019081526020016000205414155b15610cfe57610cfe84610c9a6118f2565b610cf985604051806060016040528060288152602001612d17602891396001600160a01b038a16600090815260996020526040812090610cd86118f2565b6001600160a01b031681526020810191909152604001600020549190611b36565b6118f6565b5060019392505050565b6000610d12611b62565b610d1c8583611d49565b50600083815260d0602090815260408083206001600160a01b0380871680865291845282852080546001810190915588865260d1855283862083875285528386208187529094529382902085905590519192909186918816907f882df69720ac5a9356b84d2aaa32d0c105b24cab60e885ba3d69b77090ff05c690610da49086908890612c78565b60405180910390a4949350505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b609d5460ff1690565b6000610deb610af3565b905090565b6000610deb611d54565b60d55481565b600061078c610e0d6118f2565b84610cf98560996000610e1e6118f2565b6001600160a01b03908116825260208083019390935260409182016000908120918c1681529252902054906119bf565b600090565b60cb546000906001600160a01b03163314610e805760405162461bcd60e51b81526004016109f490612c11565b610e8983610796565b905081811015610e97578091505b610ea18383611d5a565b9392505050565b6001600160a01b031660009081526098602052604090205490565b60d160209081526000938452604080852082529284528284209052825290205481565b60cb546001600160a01b03163314610f105760405162461bcd60e51b81526004016109f490612c11565b60d49190915560d555565b6000826000610f2982610796565b6001600160a01b038316600090815260cf60205260409020549091508114610f74576001600160a01b038216600090815260cf6020908152604080832084905560d390915290204290555b60cb546001600160a01b03163314610f9e5760405162461bcd60e51b81526004016109f490612c11565b6001600160a01b038516600090815260cf6020526040902054610fc190856119bf565b6001600160a01b038616600081815260cf60205260409081902083905551919450907f82c1124ee47307c0e1b36269db77162e01d791c0847be46c4c382c3904a36b69906110129087908790612c78565b60405180910390a2505092915050565b60006020819052908152604090205481565b60006110496110416118f2565b858585610d08565b949350505050565b7f8452bf83368fd24f930388bb8032e83547faee72dbe22b73045150c5e682d66281565b609c8054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561076e5780601f106107435761010080835404028352916020019161076e565b606081518351146110f95760405162461bcd60e51b81526004016109f490612b51565b825167ffffffffffffffff8111801561111157600080fd5b5060405190808252806020026020018201604052801561113b578160200160208202803683370190505b50905060005b8351811015610bbc5761117a84828151811061115957fe5b602002602001015184838151811061116d57fe5b6020026020010151610e53565b82828151811061118657fe5b6020908102919091010152600101611141565b600061078c6111a66118f2565b84610cf985604051806060016040528060258152602001612d3f60259139609960006111d06118f2565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190611b36565b611209611b62565b600085815260d2602090815260408083206001600160a01b03881684528252808320868452909152902054156112515760405162461bcd60e51b81526004016109f490612a71565b805160cb54604051636dd5b69d60e01b81526001600160a01b0390911690636dd5b69d90611293906c6d696e5369676e61747572657360981b906004016127a3565b60206040518083038186803b1580156112ab57600080fd5b505afa1580156112bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112e3919061258c565b8110156113025760405162461bcd60e51b81526004016109f490612917565b60005b8181101561159e5760005b818110156113805783818151811061132457fe5b6020026020010151600001516001600160a01b031684838151811061134557fe5b6020026020010151600001516001600160a01b031614156113785760405162461bcd60e51b81526004016109f4906129e4565b600101611310565b5060007f8452bf83368fd24f930388bb8032e83547faee72dbe22b73045150c5e682d662888888888887815181106113b457fe5b6020026020010151600001516040516020016113d596959493929190612804565b604051602081830303815290604052805190602001209050600060ca5482604051602001611404929190612725565b604051602081830303815290604052805190602001209050600060018287868151811061142d57fe5b60200260200101516020015188878151811061144557fe5b60200260200101516040015189888151811061145d57fe5b602002602001015160600151604051600081526020016040526040516114869493929190612838565b6020604051602081039080840390855afa1580156114a8573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166114db5760405162461bcd60e51b81526004016109f4906128ec565b8584815181106114e757fe5b6020026020010151600001516001600160a01b0316816001600160a01b0316146115235760405162461bcd60e51b81526004016109f490612add565b61154486858151811061153257fe5b60200260200101516000015188611d5a565b50806001600160a01b0316888a6001600160a01b03167fc1eec22a7978d1b4b28441f2aaf2119e35d06f3aaff9a37f1b64cec88c1ab28b8d8b60405161158b929190612c78565b60405180910390a4505050600101611305565b50600086815260d2602090815260408083206001600160a01b0389168452825280832087845290915290208390556115d68584611e27565b83856001600160a01b0316877fa67d828453163879637ade5a7d51abb746669dbc34d7e2149e8fec3bf71fff548660405161161191906127a3565b60405180910390a4505050505050565b600061078c61162e6118f2565b8484611a14565b60cb546001600160a01b031681565b428410156116645760405162461bcd60e51b81526004016109f490612a49565b600061166e610df0565b6001600160a01b0389166000908152602081815260409182902080546001810190915591516116c9927f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9928d928d928d9290918d91016127ac565b604051602081830303815290604052805190602001206040516020016116f0929190612725565b60405160208183030381529060405280519060200120905060006001828686866040516000815260200160405260405161172d9493929190612838565b6020604051602081039080840390855afa15801561174f573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116158015906117855750886001600160a01b0316816001600160a01b0316145b6117a15760405162461bcd60e51b81526004016109f490612a12565b6117ac8989896118f6565b505050505050505050565b60ce546001600160a01b031681565b6000610deb30610ea8565b6001600160a01b03918216600090815260996020908152604080832093909416825291909152205490565b603354610100900460ff16806118155750611815611a0a565b80611823575060335460ff16155b61183f5760405162461bcd60e51b81526004016109f490612b03565b603354610100900460ff1615801561186a576033805460ff1961ff0019909116610100171660011790555b611872611e36565b61187c8585611eb9565b61188583611f72565b61188f8683611f88565b61189987876109b1565b80156118ab576033805461ff00191690555b50505050505050565b60d36020526000908152604090205481565b60cd546001600160a01b031681565b60d060209081526000928352604080842090915290825290205481565b3390565b610aee838383612048565b60008261191057506000610790565b8282028284828161191d57fe5b0414610ea15760405162461bcd60e51b81526004016109f490612a9c565b6000610ea183836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506120ef565b6000610ea183836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611b36565b600082820183811015610ea15760405162461bcd60e51b81526004016109f490612985565b60008183106119f35781610ea1565b5090919050565b6000818310156119f35781610ea1565b303b1590565b4690565b6001600160a01b038316611a3a5760405162461bcd60e51b81526004016109f490612b88565b6001600160a01b038216611a605760405162461bcd60e51b81526004016109f4906128a9565b611a6b838383610aee565b611aa881604051806060016040528060268152602001612cf1602691396001600160a01b0386166000908152609860205260409020549190611b36565b6001600160a01b038085166000908152609860205260408082209390935590841681522054611ad790826119bf565b6001600160a01b0380841660008181526098602052604090819020939093559151908516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90611b299085906127a3565b60405180910390a3505050565b60008184841115611b5a5760405162461bcd60e51b81526004016109f49190612856565b505050900390565b60cb54604051636dd5b69d60e01b8152611bf8916001600160a01b031690636dd5b69d90611b9a906266656560e81b906004016127a3565b60206040518083038186803b158015611bb257600080fd5b505afa158015611bc6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bea919061258c565b67016345785d8a00006119e4565b341015611c175760405162461bcd60e51b81526004016109f4906129bc565b60cb54604051636dd5b69d60e01b81526000916001600160a01b031690636dd5b69d90611c509064666565546f60d81b906004016127a3565b60206040518083038186803b158015611c6857600080fd5b505afa158015611c7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ca0919061258c565b90506001600160a01b038116611cbe575060cb546001600160a01b03165b6040516001600160a01b038216903480156108fc02916000818181858888f19350505050158015611cf3573d6000803e3d6000fd5b50806001600160a01b0316611d066118f2565b6001600160a01b03167fc0d39cf3434f9dede81e427dbbccd901073df1b746711cb6cb7db1b27ddd692734604051611d3e91906127a3565b60405180910390a350565b610aee823083610c10565b60ca5490565b6000826000611d6882610796565b6001600160a01b038316600090815260cf60205260409020549091508114611db3576001600160a01b038216600090815260cf6020908152604080832084905560d390915290204290555b6001600160a01b038516600090815260cf6020526040902054611dd6908561197d565b6001600160a01b038616600081815260cf60205260409081902083905551919450907f90306653b3fe6cfd6b56d472373de671e8ded7dc29635ab2b328e491f4b55515906110129087908790612c78565b611e32308383611a14565b5050565b603354610100900460ff1680611e4f5750611e4f611a0a565b80611e5d575060335460ff16155b611e795760405162461bcd60e51b81526004016109f490612b03565b603354610100900460ff16158015611ea4576033805460ff1961ff0019909116610100171660011790555b8015611eb6576033805461ff00191690555b50565b603354610100900460ff1680611ed25750611ed2611a0a565b80611ee0575060335460ff16155b611efc5760405162461bcd60e51b81526004016109f490612b03565b603354610100900460ff16158015611f27576033805460ff1961ff0019909116610100171660011790555b8251611f3a90609b906020860190612126565b508151611f4e90609c906020850190612126565b50609d805460ff191660121790558015610aee576033805461ff0019169055505050565b609d805460ff191660ff92909216919091179055565b6001600160a01b038216611fae5760405162461bcd60e51b81526004016109f490612c41565b611fba60008383610aee565b609a54611fc790826119bf565b609a556001600160a01b038216600090815260986020526040902054611fed90826119bf565b6001600160a01b0383166000818152609860205260408082209390935591519091907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9061203c9085906127a3565b60405180910390a35050565b6001600160a01b03831661206e5760405162461bcd60e51b81526004016109f490612bcd565b6001600160a01b0382166120945760405162461bcd60e51b81526004016109f490612943565b6001600160a01b0380841660008181526099602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590611b299085906127a3565b600081836121105760405162461bcd60e51b81526004016109f49190612856565b50600083858161211c57fe5b0495945050505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061216757805160ff1916838001178555612194565b82800160010185558215612194579182015b82811115612194578251825591602001919060010190612179565b506121a09291506121a4565b5090565b5b808211156121a057600081556001016121a5565b80356001600160a01b038116811461079057600080fd5b600082601f8301126121e0578081fd5b81356121f36121ee82612cbb565b612c94565b81815291506020808301908481018184028601820187101561221457600080fd5b60005b8481101561223357813584529282019290820190600101612217565b505050505092915050565b600082601f83011261224e578081fd5b813567ffffffffffffffff811115612264578182fd5b612277601f8201601f1916602001612c94565b915080825283602082850101111561228e57600080fd5b8060208401602084013760009082016020015292915050565b803560ff8116811461079057600080fd5b6000602082840312156122c9578081fd5b610ea183836121b9565b600080604083850312156122e5578081fd5b6122ef84846121b9565b91506122fe84602085016121b9565b90509250929050565b60008060008060008060c0878903121561231f578182fd5b863561232a81612cdb565b9550602087013561233a81612cdb565b9450604087013567ffffffffffffffff80821115612356578384fd5b6123628a838b0161223e565b95506060890135915080821115612377578384fd5b5061238489828a0161223e565b935050608087013560ff8116811461239a578283fd5b8092505060a087013590509295509295509295565b6000806000606084860312156123c3578283fd5b83356123ce81612cdb565b925060208401356123de81612cdb565b929592945050506040919091013590565b600080600080600080600060e0888a031215612409578081fd5b61241389896121b9565b96506124228960208a016121b9565b9550604088013594506060880135935061243f8960808a016122a7565b925060a0880135915060c0880135905092959891949750929550565b6000806040838503121561246d578182fd5b61247784846121b9565b946020939093013593505050565b6000806000806080858703121561249a578384fd5b6124a486866121b9565b9350602085013592506124ba86604087016121b9565b9396929550929360600135925050565b600080604083850312156124dc578182fd5b823567ffffffffffffffff808211156124f3578384fd5b818501915085601f830112612506578384fd5b81356125146121ee82612cbb565b80828252602080830192508086018a828387028901011115612534578889fd5b8896505b8487101561255e5761254a8b826121b9565b845260019690960195928101928101612538565b509096508701359350505080821115612575578283fd5b50612582858286016121d0565b9150509250929050565b60006020828403121561259d578081fd5b5051919050565b600080604083850312156125b6578182fd5b823591506122fe84602085016121b9565b6000806000606084860312156125db578081fd5b833592506125ec85602086016121b9565b9150604084013590509250925092565b600080600080600060a08688031215612613578283fd5b853594506020612625888289016121b9565b9450604087013593506060870135925060808088013567ffffffffffffffff81111561264f578384fd5b8801601f81018a1361265f578384fd5b803561266d6121ee82612cbb565b81815284810190838601858402850187018e1015612689578788fd5b8794505b838510156126f05785818f0312156126a3578788fd5b6126ac86612c94565b6126b68f836121b9565b81526126c48f8984016122a7565b81890152604082810135908201526060808301359082015283526001949094019391860191850161268d565b508096505050505050509295509295909350565b60008060408385031215612716578182fd5b50508035926020909101359150565b61190160f01b81526002810192909252602282015260420190565b6001600160a01b0391909116815260200190565b6020808252825182820181905260009190848201906040850190845b8181101561278c57835183529284019291840191600101612770565b50909695505050505050565b901515815260200190565b90815260200190565b9586526001600160a01b0394851660208701529290931660408501526060840152608083019190915260a082015260c00190565b938452602084019290925260408301526001600160a01b0316606082015260800190565b95865260208601949094526001600160a01b039283166040860152606085019190915260808401521660a082015260c00190565b93845260ff9290921660208401526040830152606082015260800190565b6000602080835283518082850152825b8181101561288257858101830151858201604001528201612866565b818111156128935783604083870101525b50601f01601f1916929092016040019392505050565b60208082526023908201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260408201526265737360e81b606082015260800190565b602080825260119082015270696e76616c6964207369676e617475726560781b604082015260600190565b602080825260129082015271746f6f20666577207369676e61747572657360701b604082015260600190565b60208082526022908201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604082015261737360f01b606082015260800190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252600e908201526d66656520697320746f6f206c6f7760901b604082015260600190565b60208082526014908201527372657065746974697665207369676e61746f727960601b604082015260600190565b60208082526018908201527f7065726d697420494e56414c49445f5349474e41545552450000000000000000604082015260600190565b6020808252600e908201526d1c195c9b5a5d081156141254915160921b604082015260600190565b60208082526011908201527077697468647261776e20616c726561647960781b604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252600c908201526b1d5b985d5d1a1bdc9a5e995960a21b604082015260600190565b6020808252602e908201527f436f6e747261637420696e7374616e63652068617320616c726561647920626560408201526d195b881a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526019908201527f74776f206172726179206c656e7468206e6f7420657175616c00000000000000604082015260600190565b60208082526025908201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604082015264647265737360d81b606082015260800190565b60208082526024908201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646040820152637265737360e01b606082015260800190565b6020808252601690820152754f6e6c792063616c6c656420627920466163746f727960501b604082015260600190565b6020808252601f908201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604082015260600190565b918252602082015260400190565b60ff91909116815260200190565b60405181810167ffffffffffffffff81118282101715612cb357600080fd5b604052919050565b600067ffffffffffffffff821115612cd1578081fd5b5060209081020190565b6001600160a01b0381168114611eb657600080fdfe45524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa264697066735822122069e4924cbd794154b48449dfb9307dc38834094e30e684eed0ab65d52854b8fe64736f6c634300060c0033
Deployed ByteCode Sourcemap
96177:1820:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37755:83;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;39861:169;;;;;;;;;;-1:-1:-1;39861:169:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;84167:654::-;;;;;;;;;;-1:-1:-1;84167:654:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;82825:26::-;;;;;;;;;;;;;:::i;96628:347::-;;;;;;;;;;-1:-1:-1;96628:347:0;;;;;:::i;:::-;;:::i;:::-;;38830:100;;;;;;;;;;;;;:::i;84891:403::-;;;;;;;;;;-1:-1:-1;84891:403:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;82521:122::-;;;;;;;;;;;;;:::i;83280:77::-;;;;;;;;;;-1:-1:-1;83280:77:0;;;;;:::i;:::-;;:::i;83523:26::-;;;;;;;;;;;;;:::i;40504:410::-;;;;;;;;;;-1:-1:-1;40504:410:0;;;;;:::i;:::-;;:::i;87062:329::-;;;;;;:::i;:::-;;:::i;95136:108::-;;;;;;;;;;;;;:::i;38682:83::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;97148:98::-;;;;;;;;;;;;;:::i;96984:152::-;;;;;;;;;;;;;:::i;83556:27::-;;;;;;;;;;;;;:::i;41323:218::-;;;;;;;;;;-1:-1:-1;41323:218:0;;;;;:::i;:::-;;:::i;97378:98::-;;;;;;;;;;;;;:::i;86122:280::-;;;;;;;;;;-1:-1:-1;86122:280:0;;;;;:::i;:::-;;:::i;38993:119::-;;;;;;;;;;-1:-1:-1;38993:119:0;;;;;:::i;:::-;;:::i;83153:73::-;;;;;;;;;;-1:-1:-1;83153:73:0;;;;;:::i;:::-;;:::i;83596:153::-;;;;;;;;;;-1:-1:-1;83596:153:0;;;;;:::i;:::-;;:::i;85306:304::-;;;;;;;;;;-1:-1:-1;85306:304:0;;;;;:::i;:::-;;:::i;95325:39::-;;;;;;;;;;-1:-1:-1;95325:39:0;;;;;:::i;:::-;;:::i;86878:172::-;;;;;;:::i;:::-;;:::i;82372:142::-;;;;;;;;;;;;;:::i;37957:87::-;;;;;;;;;;;;;:::i;85707:403::-;;;;;;;;;;-1:-1:-1;85707:403:0;;;;;:::i;:::-;;:::i;42044:269::-;;;;;;;;;;-1:-1:-1;42044:269:0;;;;;:::i;:::-;;:::i;87582:1315::-;;;;;;:::i;:::-;;:::i;39325:175::-;;;;;;;;;;-1:-1:-1;39325:175:0;;;;;:::i;:::-;;:::i;82796:22::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;95373:668::-;;;;;;;;;;-1:-1:-1;95373:668:0;;;;;:::i;:::-;;:::i;82885:23::-;;;;;;;;;;;;;:::i;97258:108::-;;;;;;;;;;;;;:::i;39563:151::-;;;;;;;;;;-1:-1:-1;39563:151:0;;;;;:::i;:::-;;:::i;96245:377::-;;;;;;;;;;-1:-1:-1;96245:377:0;;;;;:::i;:::-;;:::i;83409:54::-;;;;;;;;;;-1:-1:-1;83409:54:0;;;;;:::i;:::-;;:::i;82858:20::-;;;;;;;;;;;;;:::i;83032:60::-;;;;;;;;;;-1:-1:-1;83032:60:0;;;;;:::i;:::-;;:::i;37755:83::-;37825:5;37818:12;;;;;;;;-1:-1:-1;;37818:12:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37792:13;;37818:12;;37825:5;;37818:12;;37825:5;37818:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37755:83;:::o;39861:169::-;39944:4;39961:39;39970:12;:10;:12::i;:::-;39984:7;39993:6;39961:8;:39::i;:::-;-1:-1:-1;40018:4:0;39861:169;;;;;:::o;84167:654::-;-1:-1:-1;;;;;84267:22:0;;84236:10;84267:22;;;:11;:22;;;;;;84314:14;;84267:22;;84236:10;84314:85;;84363:7;;84355:44;;-1:-1:-1;;;84355:44:0;;-1:-1:-1;;;;;84363:7:0;;;;84355:26;;:44;;-1:-1:-1;;;84382:16:0;84355:44;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;84314:85;;;84337:14;;84314:85;84300:99;;84410:11;84424:15;;84443:1;84424:20;;:86;;84473:7;;84465:45;;-1:-1:-1;;;84465:45:0;;-1:-1:-1;;;;;84473:7:0;;;;84465:26;;:45;;-1:-1:-1;;;84492:17:0;84465:45;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;84424:86;;;84447:15;;84424:86;84410:100;-1:-1:-1;84524:10:0;;;:25;;-1:-1:-1;84538:11:0;;84524:25;:47;;;;-1:-1:-1;;84553:6:0;:18;84524:47;84521:77;;;84586:12;;;;84521:77;84609:13;84625:26;84646:4;84625:16;84635:5;84625;:3;:5::i;:::-;:9;;:16::i;:::-;:20;;:26::i;:::-;-1:-1:-1;;;;;84696:32:0;;84662:10;84696:32;;;:21;:32;;;;;;84609:42;;-1:-1:-1;84662:10:0;84675:67;;84735:6;;84675:55;;84688:41;;:3;;:7;:41::i;:::-;84675:8;;:12;:55::i;:67::-;84662:80;-1:-1:-1;84760:53:0;84769:5;84776:36;84785:8;84795:16;84769:5;84662:80;84795:9;:16::i;:::-;84776:8;:36::i;:::-;84760:8;:53::i;:::-;84753:60;;;;;;84167:654;;;;:::o;82825:26::-;;;;:::o;96628:347::-;17618:12;;;;;;;;:31;;;17634:15;:13;:15::i;:::-;17618:47;;;-1:-1:-1;17654:11:0;;;;17653:12;17618:47;17610:106;;;;-1:-1:-1;;;17610:106:0;;;;;;;:::i;:::-;;;;;;;;;17748:12;;;;;;;17747:13;17767:83;;;;17796:12;:19;;-1:-1:-1;;;;17796:19:0;;;;;17824:18;17811:4;17824:18;;;17767:83;96735:7:::1;:18:::0;;-1:-1:-1;;;;;;96735:18:0::1;-1:-1:-1::0;;;;;96735:18:0;::::1;;::::0;;96778:10:::1;:8;:10::i;:::-;96764:11;:24:::0;96799:5:::1;:18:::0;;-1:-1:-1;;;;;;96799:18:0;;::::1;::::0;;;96828:8:::1;:20:::0;;;;::::1;-1:-1:-1::0;;;;;96828:20:0;::::1;;::::0;;82563:80:::1;96933:6;:4;:6::i;:::-;96917:24;;;;;;96943:10;:8;:10::i;:::-;96963:4;96889:80;;;;;;;;;;;:::i;:::-;;::::0;;-1:-1:-1;;96889:80:0;;::::1;::::0;;;;;;96879:91;;96889:80:::1;96879:91:::0;;::::1;::::0;96859:17:::1;:111:::0;17868:57;;;;17897:12;:20;;-1:-1:-1;;17897:20:0;;;17868:57;96628:347;;;:::o;38830:100::-;38910:12;;38830:100;:::o;84891:403::-;85001:20;85064:10;:17;85042:11;:18;:39;85034:77;;;;-1:-1:-1;;;85034:77:0;;;;;;;:::i;:::-;85142:11;:18;85131:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;85131:30:0;;85122:39;;85176:6;85172:114;85188:11;:18;85186:1;:20;85172:114;;;85238:48;85256:11;85268:1;85256:14;;;;;;;;;;;;;;85272:10;85283:1;85272:13;;;;;;;;;;;;;;85238:17;:48::i;:::-;85226:6;85233:1;85226:9;;;;;;;;;;;;;;;;;:60;85208:3;;85172:114;;;;84891:403;;;;:::o;82521:122::-;82563:80;82521:122;:::o;83280:77::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;83523:26::-;;;;:::o;40504:410::-;40610:4;40627:36;40637:6;40645:9;40656:6;40627:9;:36::i;:::-;40687:12;:10;:12::i;:::-;-1:-1:-1;;;;;40677:22:0;:6;-1:-1:-1;;;;;40677:22:0;;;:71;;;;-1:-1:-1;;;;;;40703:19:0;;;;;;:11;:19;;;;;-1:-1:-1;;40745:2:0;40723:12;:10;:12::i;:::-;-1:-1:-1;;;;;40703:33:0;-1:-1:-1;;;;;40703:33:0;;;;;;;;;;;;;:45;;40677:71;40674:210;;;40763:121;40772:6;40780:12;:10;:12::i;:::-;40794:89;40832:6;40794:89;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;40794:19:0;;;;;;:11;:19;;;;;;40814:12;:10;:12::i;:::-;-1:-1:-1;;;;;40794:33:0;;;;;;;;;;;;-1:-1:-1;40794:33:0;;;:89;:37;:89::i;:::-;40763:8;:121::i;:::-;-1:-1:-1;40902:4:0;40504:410;;;;;:::o;87062:329::-;87167:10;87190:12;:10;:12::i;:::-;87213:23;87223:4;87229:6;87213:9;:23::i;:::-;-1:-1:-1;87255:20:0;;;;:9;:20;;;;;;;;-1:-1:-1;;;;;87255:24:0;;;;;;;;;;;;:26;;;;;;;;87292:15;;;:4;:15;;;;;:19;;;;;;;;:26;;;;;;;;;;:35;;;87343:40;;87255:26;;:24;;87265:9;;87343:40;;;;;;;87255:26;;87321:6;;87343:40;:::i;:::-;;;;;;;;87062:329;;;;;;:::o;95136:108::-;95178:66;95136:108;:::o;38682:83::-;38748:9;;;;38682:83;:::o;97148:98::-;97201:4;97225:13;:11;:13::i;:::-;97218:20;;97148:98;:::o;96984:152::-;97071:7;97098:30;:28;:30::i;83556:27::-;;;;:::o;41323:218::-;41411:4;41428:83;41437:12;:10;:12::i;:::-;41451:7;41460:50;41499:10;41460:11;:25;41472:12;:10;:12::i;:::-;-1:-1:-1;;;;;41460:25:0;;;;;;;;;;;;;;;;;-1:-1:-1;41460:25:0;;;:34;;;;;;;;;;;:38;:50::i;97378:98::-;97439:4;97378:98;:::o;86122:280::-;83815:7;;86220:10;;-1:-1:-1;;;;;83815:7:0;83801:10;:21;83793:56;;;;-1:-1:-1;;;83793:56:0;;;;;;;:::i;:::-;86251:22:::1;86263:9;86251:11;:22::i;:::-;86243:30;;86295:9;86287:5;:17;86284:52;;;86331:5;86319:17;;86284:52;86354:40;86373:9;86384;86354:18;:40::i;:::-;86347:47:::0;86122:280;-1:-1:-1;;;86122:280:0:o;38993:119::-;-1:-1:-1;;;;;39086:18:0;39059:7;39086:18;;;:9;:18;;;;;;;38993:119::o;83153:73::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;83596:153::-;83815:7;;-1:-1:-1;;;;;83815:7:0;83801:10;:21;83793:56;;;;-1:-1:-1;;;83793:56:0;;;;;;;:::i;:::-;83683:14:::1;:23:::0;;;;83717:15:::1;:24:::0;83596:153::o;85306:304::-;85431:10;85399:9;83944:10;83957:22;83969:9;83957:11;:22::i;:::-;-1:-1:-1;;;;;83993:22:0;;;;;;:11;:22;;;;;;83944:35;;-1:-1:-1;83993:31:0;;83990:146;;-1:-1:-1;;;;;84041:22:0;;;;;;:11;:22;;;;;;;;:30;;;84086:21;:32;;;;;84121:3;84086:38;;83990:146;83815:7:::1;::::0;-1:-1:-1;;;;;83815:7:0::1;83801:10;:21;83793:56;;;;-1:-1:-1::0;;;83793:56:0::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;85462:22:0;::::2;;::::0;;;:11:::2;:22;::::0;;;;;:37:::2;::::0;85489:9;85462:26:::2;:37::i;:::-;-1:-1:-1::0;;;;;85510:22:0;::::2;;::::0;;;:11:::2;:22;::::0;;;;;;:30;;;85556:46;85454:45;;-1:-1:-1;85510:22:0;85556:46:::2;::::0;::::2;::::0;85585:9;;85454:45;;85556:46:::2;:::i;:::-;;;;;;;;85306:304:::0;;;;;;:::o;95325:39::-;;;;;;;;;;;;;;:::o;86878:172::-;86967:10;86997:45;87006:12;:10;:12::i;:::-;87020:9;87031:2;87035:6;86997:8;:45::i;:::-;86990:52;86878:172;-1:-1:-1;;;;86878:172:0:o;82372:142::-;82415:99;82372:142;:::o;37957:87::-;38029:7;38022:14;;;;;;;;-1:-1:-1;;38022:14:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37996:13;;38022:14;;38029:7;;38022:14;;38029:7;38022:14;;;;;;;;;;;;;;;;;;;;;;;;85707:403;85817:20;85880:10;:17;85858:11;:18;:39;85850:77;;;;-1:-1:-1;;;85850:77:0;;;;;;;:::i;:::-;85958:11;:18;85947:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;85947:30:0;;85938:39;;85992:6;85988:114;86004:11;:18;86002:1;:20;85988:114;;;86054:48;86072:11;86084:1;86072:14;;;;;;;;;;;;;;86088:10;86099:1;86088:13;;;;;;;;;;;;;;86054:17;:48::i;:::-;86042:6;86049:1;86042:9;;;;;;;;;;;;;;;;;:60;86024:3;;85988:114;;42044:269;42137:4;42154:129;42163:12;:10;:12::i;:::-;42177:7;42186:96;42225:15;42186:96;;;;;;;;;;;;;;;;;:11;:25;42198:12;:10;:12::i;:::-;-1:-1:-1;;;;;42186:25:0;;;;;;;;;;;;;;;;;-1:-1:-1;42186:25:0;;;:34;;;;;;;;;;;:96;:38;:96::i;87582:1315::-;87730:12;:10;:12::i;:::-;87761:21;;;;:8;:21;;;;;;;;-1:-1:-1;;;;;87761:25:0;;;;;;;;;:32;;;;;;;;;:37;87753:67;;;;-1:-1:-1;;;87753:67:0;;;;;;;:::i;:::-;87840:17;;87889:7;;87881:43;;-1:-1:-1;;;87881:43:0;;-1:-1:-1;;;;;87889:7:0;;;;87881:26;;:43;;-1:-1:-1;;;87908:15:0;87881:43;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;87876:1;:48;;87868:79;;;;-1:-1:-1;;;87868:79:0;;;;;;;:::i;:::-;87962:6;87958:794;87974:1;87972;:3;87958:794;;;88001:6;87997:124;88013:1;88011;:3;87997:124;;;88073:10;88084:1;88073:13;;;;;;;;;;;;;;:23;;;-1:-1:-1;;;;;88046:50:0;:10;88057:1;88046:13;;;;;;;;;;;;;;:23;;;-1:-1:-1;;;;;88046:50:0;;;88038:83;;;;-1:-1:-1;;;88038:83:0;;;;;;;:::i;:::-;88016:3;;87997:124;;;;88136:18;82415:99;88196:11;88209:2;88213:5;88220:6;88228:10;88239:1;88228:13;;;;;;;;;;;;;;:23;;;88167:85;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;88157:96;;;;;;88136:117;;88268:14;88324:17;;88343:10;88295:59;;;;;;;;;:::i;:::-;;;;;;;;;;;;;88285:70;;;;;;88268:87;;88370:17;88390:68;88400:6;88408:10;88419:1;88408:13;;;;;;;;;;;;;;:15;;;88425:10;88436:1;88425:13;;;;;;;;;;;;;;:15;;;88442:10;88453:1;88442:13;;;;;;;;;;;;;;:15;;;88390:68;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;88390:68:0;;-1:-1:-1;;88390:68:0;;;-1:-1:-1;;;;;;;88481:23:0;;88473:53;;;;-1:-1:-1;;;88473:53:0;;;;;;;:::i;:::-;88562:10;88573:1;88562:13;;;;;;;;;;;;;;:23;;;-1:-1:-1;;;;;88549:36:0;:9;-1:-1:-1;;;;;88549:36:0;;88541:61;;;;-1:-1:-1;;;88541:61:0;;;;;;;:::i;:::-;88617:51;88636:10;88647:1;88636:13;;;;;;;;;;;;;;:23;;;88661:6;88617:18;:51::i;:::-;;88730:9;-1:-1:-1;;;;;88688:52:0;88715:5;88711:2;-1:-1:-1;;;;;88688:52:0;;88698:11;88722:6;88688:52;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;;;87977:3:0;;87958:794;;;-1:-1:-1;88762:21:0;;;;:8;:21;;;;;;;;-1:-1:-1;;;;;88762:25:0;;;;;;;;;:32;;;;;;;;:41;;;88814:20;88784:2;88797:6;88814:8;:20::i;:::-;88875:5;88871:2;-1:-1:-1;;;;;88850:39:0;88858:11;88850:39;88882:6;88850:39;;;;;;:::i;:::-;;;;;;;;87582:1315;;;;;;:::o;39325:175::-;39411:4;39428:42;39438:12;:10;:12::i;:::-;39452:9;39463:6;39428:9;:42::i;82796:22::-;;;-1:-1:-1;;;;;82796:22:0;;:::o;95373:668::-;95519:15;95507:8;:27;;95499:54;;;;-1:-1:-1;;;95499:54:0;;;;;;;:::i;:::-;95564:14;95669:18;:16;:18::i;:::-;-1:-1:-1;;;;;95767:13:0;;95727:15;95767:13;;;;;;;;;;;;:15;;;;;;;;95716:77;;;;95178:66;;95744:5;;95751:7;;95760:5;;95767:15;;95784:8;;95716:77;;:::i;:::-;;;;;;;;;;;;;95706:88;;;;;;95605:204;;;;;;;;;:::i;:::-;;;;;;;;;;;;;95581:239;;;;;;95564:256;;95831:24;95858:26;95868:6;95876:1;95879;95882;95858:26;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;95858:26:0;;-1:-1:-1;;95858:26:0;;;-1:-1:-1;;;;;;;95903:30:0;;;;;;:59;;;95957:5;-1:-1:-1;;;;;95937:25:0;:16;-1:-1:-1;;;;;95937:25:0;;95903:59;95895:96;;;;-1:-1:-1;;;95895:96:0;;;;;;;:::i;:::-;96002:31;96011:5;96018:7;96027:5;96002:8;:31::i;:::-;95373:668;;;;;;;;;:::o;82885:23::-;;;-1:-1:-1;;;;;82885:23:0;;:::o;97258:108::-;97310:4;97334:24;97352:4;97334:9;:24::i;39563:151::-;-1:-1:-1;;;;;39679:18:0;;;39652:7;39679:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;39563:151::o;96245:377::-;17618:12;;;;;;;;:31;;;17634:15;:13;:15::i;:::-;17618:47;;;-1:-1:-1;17654:11:0;;;;17653:12;17618:47;17610:106;;;;-1:-1:-1;;;17610:106:0;;;;;;;:::i;:::-;17748:12;;;;;;;17747:13;17767:83;;;;17796:12;:19;;-1:-1:-1;;;;17796:19:0;;;;;17824:18;17811:4;17824:18;;;17767:83;96427:26:::1;:24;:26::i;:::-;96458:38;96481:5;96488:7;96458:22;:38::i;:::-;96501:25;96516:9;96501:14;:25::i;:::-;96531:30;96537:9;96548:12;96531:5;:30::i;:::-;96566:51;96597:8;96607:9;96566:30;:51::i;:::-;17872:14:::0;17868:57;;;17897:12;:20;;-1:-1:-1;;17897:20:0;;;17868:57;96245:377;;;;;;;:::o;83409:54::-;;;;;;;;;;;;;:::o;82858:20::-;;;-1:-1:-1;;;;;82858:20:0;;:::o;83032:60::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;19543:106::-;19631:10;19543:106;:::o;97488:193::-;97624:49;97650:5;97657:7;97666:6;97624:25;:49::i;25361:471::-;25419:7;25664:6;25660:47;;-1:-1:-1;25694:1:0;25687:8;;25660:47;25731:5;;;25735:1;25731;:5;:1;25755:5;;;;;:10;25747:56;;;;-1:-1:-1;;;25747:56:0;;;;;;;:::i;26300:132::-;26358:7;26385:39;26389:1;26392;26385:39;;;;;;;;;;;;;;;;;:3;:39::i;24368:136::-;24426:7;24453:43;24457:1;24460;24453:43;;;;;;;;;;;;;;;;;:3;:43::i;23912:181::-;23970:7;24002:5;;;24026:6;;;;24018:46;;;;-1:-1:-1;;;24018:46:0;;;;;;;:::i;22655:106::-;22713:7;22744:1;22740;:5;:13;;22752:1;22740:13;;;-1:-1:-1;22748:1:0;;22655:106;-1:-1:-1;22655:106:0:o;22472:107::-;22530:7;22562:1;22557;:6;;:14;;22570:1;22557:14;;18019:508;18436:4;18482:17;18514:7;18019:508;:::o;82071:98::-;82151:9;;82143:19::o;42803:539::-;-1:-1:-1;;;;;42909:20:0;;42901:70;;;;-1:-1:-1;;;42901:70:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;42990:23:0;;42982:71;;;;-1:-1:-1;;;42982:71:0;;;;;;;:::i;:::-;43066:47;43087:6;43095:9;43106:6;43066:20;:47::i;:::-;43146:71;43168:6;43146:71;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;43146:17:0;;;;;;:9;:17;;;;;;;:71;:21;:71::i;:::-;-1:-1:-1;;;;;43126:17:0;;;;;;;:9;:17;;;;;;:91;;;;43251:20;;;;;;;:32;;43276:6;43251:24;:32::i;:::-;-1:-1:-1;;;;;43228:20:0;;;;;;;:9;:20;;;;;;;:55;;;;43299:35;;;;;;;;;;43327:6;;43299:35;:::i;:::-;;;;;;;;42803:539;;;:::o;24799:192::-;24885:7;24921:12;24913:6;;;;24905:29;;;;-1:-1:-1;;;24905:29:0;;;;;;;;:::i;:::-;-1:-1:-1;;;24957:5:0;;;24799:192::o;89221:405::-;89309:7;;89301:33;;-1:-1:-1;;;89301:33:0;;89292:54;;-1:-1:-1;;;;;89309:7:0;;89301:26;;:33;;-1:-1:-1;;;89328:5:0;89301:33;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;89336:9;89292:8;:54::i;:::-;89279:9;:67;;89271:94;;;;-1:-1:-1;;;89271:94:0;;;;;;;:::i;:::-;89416:7;;89408:35;;-1:-1:-1;;;89408:35:0;;89376:21;;-1:-1:-1;;;;;89416:7:0;;89408:26;;:35;;-1:-1:-1;;;89435:7:0;89408:35;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;89376:68;-1:-1:-1;;;;;;89458:19:0;;89455:70;;-1:-1:-1;89516:7:0;;-1:-1:-1;;;;;89516:7:0;89455:70;89536:25;;-1:-1:-1;;;;;89536:14:0;;;89551:9;89536:25;;;;;;;;;89551:9;89536:14;:25;;;;;;;;;;;;;;;;;;;;;89601:5;-1:-1:-1;;;;;89577:41:0;89587:12;:10;:12::i;:::-;-1:-1:-1;;;;;89577:41:0;;89608:9;89577:41;;;;;;:::i;:::-;;;;;;;;89221:405;:::o;97693:132::-;97776:41;97789:4;97803;97810:6;97776:12;:41::i;82691:97::-;82767:17;;82691:97;:::o;86414:295::-;86530:10;86510:9;83944:10;83957:22;83969:9;83957:11;:22::i;:::-;-1:-1:-1;;;;;83993:22:0;;;;;;:11;:22;;;;;;83944:35;;-1:-1:-1;83993:31:0;;83990:146;;-1:-1:-1;;;;;84041:22:0;;;;;;:11;:22;;;;;;;;:30;;;84086:21;:32;;;;;84121:3;84086:38;;83990:146;-1:-1:-1;;;;;86561:22:0;::::1;;::::0;;;:11:::1;:22;::::0;;;;;:37:::1;::::0;86588:9;86561:26:::1;:37::i;:::-;-1:-1:-1::0;;;;;86609:22:0;::::1;;::::0;;;:11:::1;:22;::::0;;;;;;:30;;;86655:46;86553:45;;-1:-1:-1;86609:22:0;86655:46:::1;::::0;::::1;::::0;86684:9;;86553:45;;86655:46:::1;:::i;97833:127::-:0;97916:36;97934:4;97941:2;97945:6;97916:9;:36::i;:::-;97833:127;;:::o;19464:69::-;17618:12;;;;;;;;:31;;;17634:15;:13;:15::i;:::-;17618:47;;;-1:-1:-1;17654:11:0;;;;17653:12;17618:47;17610:106;;;;-1:-1:-1;;;17610:106:0;;;;;;;:::i;:::-;17748:12;;;;;;;17747:13;17767:83;;;;17796:12;:19;;-1:-1:-1;;;;17796:19:0;;;;;17824:18;17811:4;17824:18;;;17767:83;17872:14;17868:57;;;17897:12;:20;;-1:-1:-1;;17897:20:0;;;17868:57;19464:69;:::o;37499:184::-;17618:12;;;;;;;;:31;;;17634:15;:13;:15::i;:::-;17618:47;;;-1:-1:-1;17654:11:0;;;;17653:12;17618:47;17610:106;;;;-1:-1:-1;;;17610:106:0;;;;;;;:::i;:::-;17748:12;;;;;;;17747:13;17767:83;;;;17796:12;:19;;-1:-1:-1;;;;17796:19:0;;;;;17824:18;17811:4;17824:18;;;17767:83;37609:12;;::::1;::::0;:5:::1;::::0;:12:::1;::::0;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;37632:16:0;;::::1;::::0;:7:::1;::::0;:16:::1;::::0;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;37659:9:0::1;:14:::0;;-1:-1:-1;;37659:14:0::1;37671:2;37659:14;::::0;;17868:57;;;;17897:12;:20;;-1:-1:-1;;17897:20:0;;;37499:184;;;:::o;45869:90::-;45930:9;:21;;-1:-1:-1;;45930:21:0;;;;;;;;;;;;45869:90::o;43623:378::-;-1:-1:-1;;;;;43707:21:0;;43699:65;;;;-1:-1:-1;;;43699:65:0;;;;;;;:::i;:::-;43777:49;43806:1;43810:7;43819:6;43777:20;:49::i;:::-;43854:12;;:24;;43871:6;43854:16;:24::i;:::-;43839:12;:39;-1:-1:-1;;;;;43910:18:0;;;;;;:9;:18;;;;;;:30;;43933:6;43910:22;:30::i;:::-;-1:-1:-1;;;;;43889:18:0;;;;;;:9;:18;;;;;;:51;;;;43956:37;;43889:18;;;43956:37;;;;43986:6;;43956:37;:::i;:::-;;;;;;;;43623:378;;:::o;45191:346::-;-1:-1:-1;;;;;45293:19:0;;45285:68;;;;-1:-1:-1;;;45285:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;45372:21:0;;45364:68;;;;-1:-1:-1;;;45364:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;45445:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;;:36;;;45497:32;;;;;45475:6;;45497:32;:::i;26920:345::-;27006:7;27108:12;27101:5;27093:28;;;;-1:-1:-1;;;27093:28:0;;;;;;;;:::i;:::-;;27132:9;27148:1;27144;:5;;;;;;;26920:345;-1:-1:-1;;;;;26920:345:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;5:130;72:20;;-1:-1;;;;;36353:54;;37262:35;;37252:2;;37311:1;;37301:12;1716:707;;1833:3;1826:4;1818:6;1814:17;1810:27;1800:2;;-1:-1;;1841:12;1800:2;1888:6;1875:20;1910:80;1925:64;1982:6;1925:64;:::i;:::-;1910:80;:::i;:::-;2018:21;;;1901:89;-1:-1;2062:4;2075:14;;;;2050:17;;;2164;;;2155:27;;;;2152:36;-1:-1;2149:2;;;2201:1;;2191:12;2149:2;2226:1;2211:206;2236:6;2233:1;2230:13;2211:206;;;3867:20;;2304:50;;2368:14;;;;2396;;;;2258:1;2251:9;2211:206;;;2215:14;;;;;1793:630;;;;:::o;2569:442::-;;2671:3;2664:4;2656:6;2652:17;2648:27;2638:2;;-1:-1;;2679:12;2638:2;2726:6;2713:20;34778:18;34770:6;34767:30;34764:2;;;-1:-1;;34800:12;34764:2;2748:65;34873:9;34854:17;;-1:-1;;34850:33;34941:4;34931:15;2748:65;:::i;:::-;2739:74;;2833:6;2826:5;2819:21;2937:3;34941:4;2928:6;2861;2919:16;;2916:25;2913:2;;;2954:1;;2944:12;2913:2;36668:6;34941:4;2861:6;2857:17;34941:4;2895:5;2891:16;36645:30;36724:1;36706:16;;;34941:4;36706:16;36699:27;2895:5;2631:380;-1:-1;;2631:380::o;4078:126::-;4143:20;;36569:4;36558:16;;37632:33;;37622:2;;37679:1;;37669:12;4211:241;;4315:2;4303:9;4294:7;4290:23;4286:32;4283:2;;;-1:-1;;4321:12;4283:2;4383:53;4428:7;4404:22;4383:53;:::i;4459:366::-;;;4580:2;4568:9;4559:7;4555:23;4551:32;4548:2;;;-1:-1;;4586:12;4548:2;4648:53;4693:7;4669:22;4648:53;:::i;:::-;4638:63;;4756:53;4801:7;4738:2;4781:9;4777:22;4756:53;:::i;:::-;4746:63;;4542:283;;;;;:::o;4832:1077::-;;;;;;;5039:3;5027:9;5018:7;5014:23;5010:33;5007:2;;;-1:-1;;5046:12;5007:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;5098:63;-1:-1;5198:2;5237:22;;72:20;97:33;72:20;97:33;:::i;:::-;5206:63;-1:-1;5334:2;5319:18;;5306:32;5358:18;5347:30;;;5344:2;;;-1:-1;;5380:12;5344:2;5410:63;5465:7;5456:6;5445:9;5441:22;5410:63;:::i;:::-;5400:73;;5538:2;5527:9;5523:18;5510:32;5496:46;;5358:18;5554:6;5551:30;5548:2;;;-1:-1;;5584:12;5548:2;;5614:63;5669:7;5660:6;5649:9;5645:22;5614:63;:::i;:::-;5604:73;;;5714:3;5756:9;5752:22;4143:20;36569:4;37658:5;36558:16;37635:5;37632:33;37622:2;;-1:-1;;37669:12;37622:2;5723:61;;;;5821:3;5865:9;5861:22;3867:20;5830:63;;5001:908;;;;;;;;:::o;5916:491::-;;;;6054:2;6042:9;6033:7;6029:23;6025:32;6022:2;;;-1:-1;;6060:12;6022:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;6112:63;-1:-1;6212:2;6251:22;;72:20;97:33;72:20;97:33;:::i;:::-;6016:391;;6220:63;;-1:-1;;;6320:2;6359:22;;;;3867:20;;6016:391::o;6414:991::-;;;;;;;;6618:3;6606:9;6597:7;6593:23;6589:33;6586:2;;;-1:-1;;6625:12;6586:2;6687:53;6732:7;6708:22;6687:53;:::i;:::-;6677:63;;6795:53;6840:7;6777:2;6820:9;6816:22;6795:53;:::i;:::-;6785:63;;6885:2;6928:9;6924:22;3867:20;6893:63;;6993:2;7036:9;7032:22;3867:20;7001:63;;7120:51;7163:7;7101:3;7143:9;7139:22;7120:51;:::i;:::-;7110:61;;7208:3;7252:9;7248:22;2498:20;7217:63;;7317:3;7361:9;7357:22;2498:20;7326:63;;6580:825;;;;;;;;;;:::o;7412:366::-;;;7533:2;7521:9;7512:7;7508:23;7504:32;7501:2;;;-1:-1;;7539:12;7501:2;7601:53;7646:7;7622:22;7601:53;:::i;:::-;7591:63;7691:2;7730:22;;;;3867:20;;-1:-1;;;7495:283::o;7785:617::-;;;;;7940:3;7928:9;7919:7;7915:23;7911:33;7908:2;;;-1:-1;;7947:12;7908:2;8009:53;8054:7;8030:22;8009:53;:::i;:::-;7999:63;;8099:2;8142:9;8138:22;3867:20;8107:63;;8225:53;8270:7;8207:2;8250:9;8246:22;8225:53;:::i;:::-;7902:500;;;;-1:-1;8215:63;;8315:2;8354:22;3867:20;;-1:-1;;7902:500::o;8409:638::-;;;8580:2;8568:9;8559:7;8555:23;8551:32;8548:2;;;-1:-1;;8586:12;8548:2;8644:17;8631:31;8682:18;;8674:6;8671:30;8668:2;;;-1:-1;;8704:12;8668:2;8795:6;8784:9;8780:22;;;277:3;270:4;262:6;258:17;254:27;244:2;;-1:-1;;285:12;244:2;332:6;319:20;354:80;369:64;426:6;369:64;:::i;354:80::-;440:16;476:6;469:5;462:21;506:4;;523:3;519:14;512:21;;506:4;498:6;494:17;628:3;506:4;;612:6;608:17;498:6;599:27;;596:36;593:2;;;-1:-1;;635:12;593:2;-1:-1;661:10;;655:206;680:6;677:1;674:13;655:206;;;760:37;793:3;781:10;760:37;:::i;:::-;748:50;;702:1;695:9;;;;;812:14;;;;840;;655:206;;;-1:-1;8724:88;;-1:-1;8862:18;;8849:32;;-1:-1;;;8890:30;;;8887:2;;;-1:-1;;8923:12;8887:2;;8953:78;9023:7;9014:6;9003:9;8999:22;8953:78;:::i;:::-;8943:88;;;8542:505;;;;;:::o;9054:263::-;;9169:2;9157:9;9148:7;9144:23;9140:32;9137:2;;;-1:-1;;9175:12;9137:2;-1:-1;4015:13;;9131:186;-1:-1;9131:186::o;9324:366::-;;;9445:2;9433:9;9424:7;9420:23;9416:32;9413:2;;;-1:-1;;9451:12;9413:2;3880:6;3867:20;9503:63;;9621:53;9666:7;9603:2;9646:9;9642:22;9621:53;:::i;9697:491::-;;;;9835:2;9823:9;9814:7;9810:23;9806:32;9803:2;;;-1:-1;;9841:12;9803:2;3880:6;3867:20;9893:63;;10011:53;10056:7;9993:2;10036:9;10032:22;10011:53;:::i;:::-;10001:63;;10101:2;10144:9;10140:22;3867:20;10109:63;;9797:391;;;;;:::o;10195:933::-;;;;;;10419:3;10407:9;10398:7;10394:23;10390:33;10387:2;;;-1:-1;;10426:12;10387:2;3880:6;3867:20;10478:63;;10578:2;10596:53;10641:7;10578:2;10621:9;10617:22;10596:53;:::i;:::-;10586:63;;10686:2;10729:9;10725:22;3867:20;10694:63;;10794:2;10837:9;10833:22;3867:20;10802:63;;10930:3;;10919:9;10915:19;10902:33;10955:18;10947:6;10944:30;10941:2;;;-1:-1;;10977:12;10941:2;11080:22;;1039:4;1027:17;;1023:27;-1:-1;1013:2;;-1:-1;;1054:12;1013:2;1101:6;1088:20;1123:107;1138:91;1222:6;1138:91;:::i;1123:107::-;1258:21;;;1315:14;;;;1290:17;;;1404;;;1395:27;;;;1392:36;-1:-1;1389:2;;;-1:-1;;1431:12;1389:2;-1:-1;1457:10;;1451:233;1476:6;1473:1;1470:13;1451:233;;;10930:3;3146:9;3141:3;3137:19;3133:30;3130:2;;;-1:-1;;3166:12;3130:2;3194:20;10930:3;3194:20;:::i;:::-;3301:49;3346:3;3322:22;3301:49;:::i;:::-;3283:16;3276:75;3442:47;3485:3;10578:2;3465:9;3461:22;3442:47;:::i;:::-;3424:16;;;3417:73;10686:2;3602:22;;;2498:20;3563:16;;;3556:75;10794:2;3743:22;;;2498:20;3704:16;;;3697:75;1544:77;;1498:1;1491:9;;;;;1635:14;;;;1663;;1451:233;;;1455:14;10997:115;;;;;;;;;10381:747;;;;;;;;:::o;11135:366::-;;;11256:2;11244:9;11235:7;11231:23;11227:32;11224:2;;;-1:-1;;11262:12;11224:2;-1:-1;;3867:20;;;11414:2;11453:22;;;3867:20;;-1:-1;11218:283::o;20280:659::-;-1:-1;;;14973:87;;14958:1;15079:11;;12721:37;;;;20791:12;;;12721:37;20902:12;;;20525:414::o;20946:222::-;-1:-1;;;;;36353:54;;;;11761:37;;21073:2;21058:18;;21044:124::o;21175:370::-;21352:2;21366:47;;;35224:12;;21337:18;;;35628:19;;;21175:370;;21352:2;35078:14;;;;35668;;;;21175:370;12249:260;12274:6;12271:1;12268:13;12249:260;;;12335:13;;12721:37;;35483:14;;;;11662;;;;12296:1;12289:9;12249:260;;;-1:-1;21419:116;;21323:222;-1:-1;;;;;;21323:222::o;21552:210::-;36186:13;;36179:21;12604:34;;21673:2;21658:18;;21644:118::o;21769:222::-;12721:37;;;21896:2;21881:18;;21867:124::o;21998:780::-;12721:37;;;-1:-1;;;;;36353:54;;;22430:2;22415:18;;11761:37;36353:54;;;;22513:2;22498:18;;11761:37;22596:2;22581:18;;12721:37;22679:3;22664:19;;12721:37;;;;36364:42;22748:19;;12721:37;22265:3;22250:19;;22236:542::o;22785:556::-;12721:37;;;23161:2;23146:18;;12721:37;;;;23244:2;23229:18;;12721:37;-1:-1;;;;;36353:54;23327:2;23312:18;;11761:37;22996:3;22981:19;;22967:374::o;23348:780::-;12721:37;;;23780:2;23765:18;;12721:37;;;;-1:-1;;;;;36353:54;;;23863:2;23848:18;;11761:37;23946:2;23931:18;;12721:37;;;;24029:3;24014:19;;12721:37;36353:54;36364:42;24098:19;;11761:37;23615:3;23600:19;;23586:542::o;24135:548::-;12721:37;;;36569:4;36558:16;;;;24503:2;24488:18;;20233:35;24586:2;24571:18;;12721:37;24669:2;24654:18;;12721:37;24342:3;24327:19;;24313:370::o;24690:310::-;;24837:2;;24858:17;24851:47;13074:5;35224:12;35640:6;24837:2;24826:9;24822:18;35628:19;-1:-1;36813:101;36827:6;36824:1;36821:13;36813:101;;;36894:11;;;;;36888:18;36875:11;;;35668:14;36875:11;36868:39;36842:10;;36813:101;;;36929:6;36926:1;36923:13;36920:2;;;-1:-1;35668:14;36985:6;24826:9;36976:16;;36969:27;36920:2;-1:-1;34873:9;37166:14;-1:-1;;37162:28;13232:39;;;;35668:14;13232:39;;24808:192;-1:-1;;;24808:192::o;25007:416::-;25207:2;25221:47;;;13508:2;25192:18;;;35628:19;13544:34;35668:14;;;13524:55;-1:-1;;;13599:12;;;13592:27;13638:12;;;25178:245::o;25430:416::-;25630:2;25644:47;;;13889:2;25615:18;;;35628:19;-1:-1;;;35668:14;;;13905:40;13964:12;;;25601:245::o;25853:416::-;26053:2;26067:47;;;14215:2;26038:18;;;35628:19;-1:-1;;;35668:14;;;14231:41;14291:12;;;26024:245::o;26276:416::-;26476:2;26490:47;;;14542:2;26461:18;;;35628:19;14578:34;35668:14;;;14558:55;-1:-1;;;14633:12;;;14626:26;14671:12;;;26447:245::o;26699:416::-;26899:2;26913:47;;;15329:2;26884:18;;;35628:19;15365:29;35668:14;;;15345:50;15414:12;;;26870:245::o;27122:416::-;27322:2;27336:47;;;15665:2;27307:18;;;35628:19;-1:-1;;;35668:14;;;15681:37;15737:12;;;27293:245::o;27545:416::-;27745:2;27759:47;;;15988:2;27730:18;;;35628:19;-1:-1;;;35668:14;;;16004:43;16066:12;;;27716:245::o;27968:416::-;28168:2;28182:47;;;16317:2;28153:18;;;35628:19;16353:26;35668:14;;;16333:47;16399:12;;;28139:245::o;28391:416::-;28591:2;28605:47;;;16650:2;28576:18;;;35628:19;-1:-1;;;35668:14;;;16666:37;16722:12;;;28562:245::o;28814:416::-;29014:2;29028:47;;;16973:2;28999:18;;;35628:19;-1:-1;;;35668:14;;;16989:40;17048:12;;;28985:245::o;29237:416::-;29437:2;29451:47;;;17299:2;29422:18;;;35628:19;17335:34;35668:14;;;17315:55;-1:-1;;;17390:12;;;17383:25;17427:12;;;29408:245::o;29660:416::-;29860:2;29874:47;;;17678:2;29845:18;;;35628:19;-1:-1;;;35668:14;;;17694:35;17748:12;;;29831:245::o;30083:416::-;30283:2;30297:47;;;17999:2;30268:18;;;35628:19;18035:34;35668:14;;;18015:55;-1:-1;;;18090:12;;;18083:38;18140:12;;;30254:245::o;30506:416::-;30706:2;30720:47;;;18391:2;30691:18;;;35628:19;18427:27;35668:14;;;18407:48;18474:12;;;30677:245::o;30929:416::-;31129:2;31143:47;;;18725:2;31114:18;;;35628:19;18761:34;35668:14;;;18741:55;-1:-1;;;18816:12;;;18809:29;18857:12;;;31100:245::o;31352:416::-;31552:2;31566:47;;;19108:2;31537:18;;;35628:19;19144:34;35668:14;;;19124:55;-1:-1;;;19199:12;;;19192:28;19239:12;;;31523:245::o;31775:416::-;31975:2;31989:47;;;19490:2;31960:18;;;35628:19;-1:-1;;;35668:14;;;19506:45;19570:12;;;31946:245::o;32198:416::-;32398:2;32412:47;;;19821:2;32383:18;;;35628:19;19857:33;35668:14;;;19837:54;19910:12;;;32369:245::o;32850:333::-;12721:37;;;33169:2;33154:18;;12721:37;33005:2;32990:18;;32976:207::o;33190:214::-;36569:4;36558:16;;;;20233:35;;33313:2;33298:18;;33284:120::o;33411:256::-;33473:2;33467:9;33499:17;;;33574:18;33559:34;;33595:22;;;33556:62;33553:2;;;33631:1;;33621:12;33553:2;33473;33640:22;33451:216;;-1:-1;33451:216::o;33674:304::-;;33833:18;33825:6;33822:30;33819:2;;;-1:-1;;33855:12;33819:2;-1:-1;33900:4;33888:17;;;33953:15;;33756:222::o;37203:117::-;-1:-1;;;;;36353:54;;37262:35;;37252:2;;37311:1;;37301:12
Swarm Source
ipfs://69e4924cbd794154b48449dfb9307dc38834094e30e684eed0ab65d52854b8fe
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.
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.