More Info
Private Name Tags
ContractCreator
Sponsored
Latest 17 from a total of 17 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Withdraw Partial... | 40944726 | 845 days ago | IN | 0 FTM | 0.10667091 | ||||
Lock Tokens | 40944524 | 845 days ago | IN | 22.2 FTM | 0.01019593 | ||||
Withdraw Partial... | 39923926 | 859 days ago | IN | 0 FTM | 0.02034931 | ||||
Withdraw Partial... | 38757326 | 875 days ago | IN | 0 FTM | 0.02188059 | ||||
Withdraw Partial... | 36387099 | 908 days ago | IN | 0 FTM | 0.04124466 | ||||
Lock Tokens | 36386996 | 908 days ago | IN | 22.2 FTM | 0.20879018 | ||||
Withdraw Partial... | 35971755 | 913 days ago | IN | 0 FTM | 0.02106753 | ||||
Lock Tokens | 35971432 | 913 days ago | IN | 22.2 FTM | 0.08929492 | ||||
Withdraw Partial... | 35227503 | 922 days ago | IN | 0 FTM | 0.02449321 | ||||
Lock Tokens | 35227168 | 922 days ago | IN | 22.2 FTM | 0.10450714 | ||||
Lock Tokens | 34984044 | 925 days ago | IN | 22.2 FTM | 0.0514884 | ||||
Withdraw | 33152449 | 946 days ago | IN | 0 FTM | 0.04433751 | ||||
Lock Tokens | 33150462 | 946 days ago | IN | 22.2 FTM | 0.12727441 | ||||
Vest Tokens | 32915667 | 949 days ago | IN | 22.2 FTM | 0.17403363 | ||||
Withdraw Partial... | 32895901 | 949 days ago | IN | 0 FTM | 0.05683242 | ||||
Lock Tokens | 32895635 | 949 days ago | IN | 22.2 FTM | 0.29517887 | ||||
0x60806040 | 31298572 | 968 days ago | IN | 0 FTM | 1.05985366 |
Latest 9 internal transactions
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
40944524 | 845 days ago | 22.2 FTM | ||||
36386996 | 908 days ago | 22.2 FTM | ||||
35971432 | 913 days ago | 22.2 FTM | ||||
35227168 | 922 days ago | 22.2 FTM | ||||
34984044 | 925 days ago | 22.2 FTM | ||||
33150462 | 946 days ago | 22.2 FTM | ||||
32915667 | 949 days ago | 22.2 FTM | ||||
32895635 | 949 days ago | 22.2 FTM | ||||
31298572 | 968 days ago | Contract Creation | 0 FTM |
Loading...
Loading
Contract Name:
CryptExLpTokenLockerV4
Compiler Version
v0.7.6+commit.7338295f
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
/* ░█████╗░██████╗░██╗░░░██╗██████╗░████████╗███████╗██╗░░██╗ ██╔══██╗██╔══██╗╚██╗░██╔╝██╔══██╗╚══██╔══╝██╔════╝╚██╗██╔╝ ██║░░╚═╝██████╔╝░╚████╔╝░██████╔╝░░░██║░░░█████╗░░░╚███╔╝░ ██║░░██╗██╔══██╗░░╚██╔╝░░██╔═══╝░░░░██║░░░██╔══╝░░░██╔██╗░ ╚█████╔╝██║░░██║░░░██║░░░██║░░░░░░░░██║░░░███████╗██╔╝╚██╗ ░╚════╝░╚═╝░░╚═╝░░░╚═╝░░░╚═╝░░░░░░░░╚═╝░░░╚══════╝╚═╝░░╚═╝ This contract for locking and vesting liquidity tokens. Locked liquidity cannot be removed from DEX until the specified unlock date has been reached. Supports several dexes. Version 4 • website: https://cryptexlock.me • medium: https://medium.com/cryptex-locker • Telegram Announcements Channel: https://t.me/CryptExAnnouncements • Telegram Main Channel: https://t.me/cryptexlocker • Twitter Page: https://twitter.com/ExLocker • Reddit: https://www.reddit.com/r/CryptExLocker/ */ // SPDX-License-Identifier: UNLICENSED pragma solidity 0.7.6; import "@openzeppelin/contracts/math/SafeMath.sol"; import "@openzeppelin/contracts/utils/EnumerableSet.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; import "@openzeppelin/contracts/utils/Address.sol"; import "../interfaces/IPancakeFactory.sol"; import "../interfaces/IPancakePair.sol"; import "../interfaces/IFeesCalculator.sol"; import "../interfaces/IMigrator.sol"; import "../LockAndVestBase.sol"; contract CryptExLpTokenLockerV4 is LockAndVestBase { using SafeMath for uint256; using SafeERC20 for IERC20; using EnumerableSet for EnumerableSet.UintSet; using Address for address; mapping(address => bool) public isFactorySupported; IMigrator public migrator; struct TokenLock { address lpToken; address owner; uint256 tokenAmount; uint256 unlockTime; uint256 lockedCrx; } mapping(uint256 => TokenLock) public tokenLocks; mapping(address => EnumerableSet.UintSet) private userLocks; event OnTokenLock( uint256 indexed lockId, address indexed tokenAddress, address indexed owner, uint256 amount, uint256 unlockTime ); event OnLockMigration(uint256 indexed lockId, address indexed migrator); modifier onlyLockOwner(uint256 lockId) { TokenLock storage lock = tokenLocks[lockId]; require( lock.owner == address(msg.sender), "NO ACTIVE LOCK OR NOT OWNER" ); _; } constructor( address[] memory supportedFactories, address _feesCalculator, address payable _feesReceiver, address _feeToken ) { feesCalculator = IFeesCalculator(_feesCalculator); feeReceiver = _feesReceiver; feeToken = IERC20(_feeToken); for (uint256 i = 0; i < supportedFactories.length; ++i) { for (uint256 j = i + 1; j < supportedFactories.length; ++j) { require( supportedFactories[i] != supportedFactories[j], "WRONG FACTORIES" ); } require( _checkIfAddressIsFactory(supportedFactories[i]), "WRONG FACTORIES" ); isFactorySupported[supportedFactories[i]] = true; } } /** * @notice allow/disallow factory for locking and vesting * @param factory factory address * @param value false - disallow, * true - allow */ function setIsFactorySupported(address factory, bool value) external onlyOwner { require(_checkIfAddressIsFactory(factory), "WRONG FACTORY"); isFactorySupported[factory] = value; } function _proceedLock( address token, address withdrawer, uint256 amountToLock, uint256 unlockTime, uint256 crxToLock, bool needToCheck ) internal virtual override returns (uint256 lockId) { if (needToCheck) { require(isLpToken(token), "NOT DEX PAIR"); } TokenLock memory lock = TokenLock({ lpToken: token, owner: withdrawer, tokenAmount: amountToLock, unlockTime: unlockTime, lockedCrx: crxToLock }); lockId = lockNonce++; tokenLocks[lockId] = lock; userLocks[withdrawer].add(lockId); IERC20(token).safeTransferFrom(msg.sender, address(this), amountToLock); emit OnTokenLock(lockId, token, withdrawer, amountToLock, unlockTime); return lockId; } function isLpToken(address lpToken) private view returns (bool) { if (!lpToken.isContract()) { return false; } IPancakePair pair = IPancakePair(lpToken); address factory; try pair.factory() returns (address _factory) { factory = _factory; } catch (bytes memory) { return false; } if (!isFactorySupported[factory]) { return false; } address factoryPair = IPancakeFactory(factory).getPair( pair.token0(), pair.token1() ); return factoryPair == lpToken; } /** * @notice increase unlock time of already locked tokens * @param newUnlockTime new unlock time (unix time in seconds) */ function extendLockTime(uint256 lockId, uint256 newUnlockTime) external nonReentrant onlyLockOwner(lockId) { require(newUnlockTime > block.timestamp, "UNLOCK TIME IN THE PAST"); require( newUnlockTime < 10000000000, "INVALID UNLOCK TIME, MUST BE UNIX TIME IN SECONDS" ); TokenLock storage lock = tokenLocks[lockId]; require(lock.unlockTime < newUnlockTime, "NOT INCREASING UNLOCK TIME"); lock.unlockTime = newUnlockTime; emit OnLockDurationIncreased(lockId, newUnlockTime); } /** * @notice add tokens to an existing lock * @param amountToIncrement tokens amount to add * @param feePaymentMode fee payment mode */ function increaseLockAmount( uint256 lockId, uint256 amountToIncrement, uint8 feePaymentMode ) external payable nonReentrant onlyLockOwner(lockId) { require(amountToIncrement > 0, "ZERO AMOUNT"); TokenLock storage lock = tokenLocks[lockId]; address _lpToken = lock.lpToken; ( uint256 actualIncrementAmount, uint256 crxToLock ) = _getIncreaseLockAmounts( _lpToken, amountToIncrement, lock.unlockTime, feePaymentMode ); lock.tokenAmount = lock.tokenAmount.add(actualIncrementAmount); lock.lockedCrx = lock.lockedCrx.add(crxToLock); IERC20(_lpToken).safeTransferFrom( msg.sender, address(this), actualIncrementAmount ); emit OnLockAmountIncreased(lockId, amountToIncrement); } /** * @notice withdraw all tokens from lock. Current time must be greater than unlock time * @param lockId lock id to withdraw */ function withdraw(uint256 lockId) external { TokenLock storage lock = tokenLocks[lockId]; withdrawPartially(lockId, lock.tokenAmount); } /** * @notice withdraw specified amount of tokens from lock. Current time must be greater than unlock time * @param lockId lock id to withdraw tokens from * @param amount amount of tokens to withdraw */ function withdrawPartially(uint256 lockId, uint256 amount) public nonReentrant onlyLockOwner(lockId) { TokenLock storage lock = tokenLocks[lockId]; require(lock.tokenAmount >= amount, "AMOUNT EXCEEDS LOCKED"); require(block.timestamp >= lock.unlockTime, "NOT YET UNLOCKED"); address _owner = lock.owner; IERC20(lock.lpToken).safeTransfer(_owner, amount); uint256 tokenAmount = lock.tokenAmount.sub(amount); lock.tokenAmount = tokenAmount; if (tokenAmount == 0) { uint256 lockedCrx = lock.lockedCrx; if (lockedCrx > 0) { feeToken.safeTransfer(_owner, lockedCrx); } //clean up storage to save gas userLocks[_owner].remove(lockId); delete tokenLocks[lockId]; emit OnTokenUnlock(lockId); } emit OnLockWithdrawal(lockId, amount); } /** * @notice transfer lock ownership to another account. If crxTokens were locked as a paymentFee, the new owner * will receive them after the unlock * @param lockId lock id to transfer * @param newOwner account to transfer lock */ function transferLock(uint256 lockId, address newOwner) external onlyLockOwner(lockId) { require(newOwner != address(0), "ZERO NEW OWNER"); TokenLock storage lock = tokenLocks[lockId]; userLocks[lock.owner].remove(lockId); userLocks[newOwner].add(lockId); lock.owner = newOwner; emit OnLockOwnershipTransferred(lockId, newOwner); } /** * @notice get user's locks number * @param user user's address */ function userLocksLength(address user) external view returns (uint256) { return userLocks[user].length(); } /** * @notice get user lock id at specified index * @param user user's address * @param index index of lock id */ function userLockAt(address user, uint256 index) external view returns (uint256) { return userLocks[user].at(index); } /** * @notice Sets the migrator contract that will perform the migration in case a new update of Pancake was * rolled out. Callable only by the owner of this contract. * @param newMigrator address of the migrator contract */ function setMigrator(address newMigrator) external onlyOwner { migrator = IMigrator(newMigrator); } /** * @notice migrates liquidity in case new update of Pancake was rolled out. * @param lockId id of the lock * @param migratorContract address of migrator contract that will perform the migration (prevents frontrun attack * if a locker owner changes the migrator contract before the migration function was mined) */ function migrate(uint256 lockId, address migratorContract) external nonReentrant { require(address(migrator) != address(0), "NO MIGRATOR"); require(migratorContract == address(migrator), "WRONG MIGRATOR"); //frontrun prevention TokenLock storage lock = tokenLocks[lockId]; require(lock.owner == msg.sender, "ONLY LOCK OWNER"); IERC20(lock.lpToken).safeApprove(address(migrator), lock.tokenAmount); migrator.migrate( lock.lpToken, lock.tokenAmount, lock.unlockTime, lock.owner ); emit OnLockMigration(lockId, address(migrator)); userLocks[lock.owner].remove(lockId); delete tokenLocks[lockId]; } /** * @notice recover accidentally sent tokens to the contract. Callable only by contract owner * @param tokenAddress token address to recover */ function recoverLockedTokens(address tokenAddress) external onlyOwner { require(!isLpToken(tokenAddress), "unable to recover LP token"); IERC20 token = IERC20(tokenAddress); token.safeTransfer(owner(), token.balanceOf(address(this))); } function _checkIfAddressIsFactory(address addressCheck) private view returns (bool) { if (!addressCheck.isContract()) { return false; } try IPancakeFactory(addressCheck).allPairsLength() returns (uint256) { return true; } catch (bytes memory) { return false; } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, 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 (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a % b); } /** * @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) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } /** * @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) { 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, reverting 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) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting 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) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * 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); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * 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; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping (bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement. bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { require(set._values.length > index, "EnumerableSet: index out of bounds"); return set._values[index]; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "./IERC20.sol"; import "../../math/SafeMath.sol"; import "../../utils/Address.sol"; /** * @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 IERC20;` 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)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ 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. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "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"); } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor () internal { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @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]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being 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 percentage 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. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor () internal { _status = _NOT_ENTERED; } /** * @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(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.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) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
//SPDX-License-Identifier: UNLICENSED pragma solidity >=0.5.0; interface IPancakeFactory { event PairCreated(address indexed token0, address indexed token1, address pair, uint); function feeTo() external view returns (address); function feeToSetter() external view returns (address); function getPair(address tokenA, address tokenB) external view returns (address pair); function allPairs(uint) external view returns (address pair); function allPairsLength() external view returns (uint); function createPair(address tokenA, address tokenB) external returns (address pair); function setFeeTo(address) external; function setFeeToSetter(address) external; }
//SPDX-License-Identifier: UNLICENSED pragma solidity >=0.5.0; interface IPancakePair { event Approval(address indexed owner, address indexed spender, uint value); event Transfer(address indexed from, address indexed to, uint value); function name() external pure returns (string memory); function symbol() external pure returns (string memory); function decimals() external pure returns (uint8); function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom(address from, address to, uint value) external returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint); function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; event Mint(address indexed sender, uint amount0, uint amount1); event Burn(address indexed sender, uint amount0, uint amount1, address indexed to); event Swap( address indexed sender, uint amount0In, uint amount1In, uint amount0Out, uint amount1Out, address indexed to ); event Sync(uint112 reserve0, uint112 reserve1); function MINIMUM_LIQUIDITY() external pure returns (uint); function factory() external view returns (address); function token0() external view returns (address); function token1() external view returns (address); function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); function price0CumulativeLast() external view returns (uint); function price1CumulativeLast() external view returns (uint); function kLast() external view returns (uint); function mint(address to) external returns (uint liquidity); function burn(address to) external returns (uint amount0, uint amount1); function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external; function skim(address to) external; function sync() external; function initialize(address, address) external; }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.7.6; interface IFeesCalculator { function calculateFees( address token, uint256 amount, uint256 unlockTime, uint8 paymentMode, address referrer, address sender ) external view returns(uint256 ethFee, uint256 systemTokenFee, uint256 tokenFee, uint256 lockAmount, uint256 referralPercentScaled); function calculateIncreaseAmountFees( address token, uint256 amount, uint256 unlockTime, uint8 paymentMode, address sender ) external view returns(uint256 ethFee, uint256 systemTokenFee, uint256 tokenFee, uint256 lockAmount); }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.7.6; interface IMigrator { function migrate(address lpToken, uint256 amount, uint256 unlockTime, address owner) external; }
/* ░█████╗░██████╗░██╗░░░██╗██████╗░████████╗███████╗██╗░░██╗ ██╔══██╗██╔══██╗╚██╗░██╔╝██╔══██╗╚══██╔══╝██╔════╝╚██╗██╔╝ ██║░░╚═╝██████╔╝░╚████╔╝░██████╔╝░░░██║░░░█████╗░░░╚███╔╝░ ██║░░██╗██╔══██╗░░╚██╔╝░░██╔═══╝░░░░██║░░░██╔══╝░░░██╔██╗░ ╚█████╔╝██║░░██║░░░██║░░░██║░░░░░░░░██║░░░███████╗██╔╝╚██╗ ░╚════╝░╚═╝░░╚═╝░░░╚═╝░░░╚═╝░░░░░░░░╚═╝░░░╚══════╝╚═╝░░╚═╝ Base functionality for locking and vesting contract. • website: https://cryptexlock.me • medium: https://medium.com/cryptex-locker • Telegram Announcements Channel: https://t.me/CryptExAnnouncements • Telegram Main Channel: https://t.me/cryptexlocker • Twitter Page: https://twitter.com/ExLocker • Reddit: https://www.reddit.com/r/CryptExLocker/ */ // SPDX-License-Identifier: UNLICENSED pragma solidity 0.7.6; import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; import "@openzeppelin/contracts/math/SafeMath.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "./interfaces/IFeesCalculator.sol"; abstract contract LockAndVestBase is ReentrancyGuard, Ownable { using SafeERC20 for IERC20; using SafeMath for uint256; IFeesCalculator public feesCalculator; address payable public feeReceiver; IERC20 public feeToken; uint256 public minimalLockTime; uint256 internal lockNonce; event OnFeesCalculatorUpdate( address lastFeesCalculator, address newFeesCalculator ); event OnFeeReceiverUpdate(address lastFeeReceiver, address newFeeReceiver); event OnFeeTokenUpdate(address newAddress); event OnMinimalLockTimeChange( uint256 oldMinimalLockTime, uint256 newMinimalLockTime ); event OnTokenUnlock(uint256 indexed lockId); event OnLockWithdrawal(uint256 indexed lockId, uint256 amount); event OnLockAmountIncreased(uint256 indexed lockId, uint256 amount); event OnLockDurationIncreased( uint256 indexed lockId, uint256 newUnlockTime ); event OnLockOwnershipTransferred( uint256 indexed lockId, address indexed newOwner ); /** * @notice locks BEP20 token until specified time * @param token token address to lock * @param amount amount of tokens to lock * @param unlockTime unix time in seconds after that tokens can be withdrawn * @param withdrawer account that can withdraw tokens to it's balance * @param feePaymentMode 0 - pay fees in ETH + % of token, * 1 - pay fees in CRX + % of token, * 2 - pay fees fully in BNB, * 3 - pay fees fully in CRX * 4 - pay fees by locking CRX * @param referrer account of referrer */ function lockTokens( address token, uint256 amount, uint256 unlockTime, address payable withdrawer, uint8 feePaymentMode, address referrer ) external payable nonReentrant returns (uint256 lockId) { require(amount > 0, "ZERO AMOUNT"); require(token != address(0), "ZERO TOKEN"); require(withdrawer != address(0), "ZERO WITHDRAWER"); require( unlockTime < 10000000000, "INVALID UNLOCK TIME, MUST BE UNIX TIME IN SECONDS" ); require( unlockTime > block.timestamp + minimalLockTime, "TOO SMALL UNLOCK TIME" ); (uint256 amountToLock, uint256 crxToLock) = _getLockAmounts( token, amount, unlockTime, feePaymentMode, referrer ); lockId = _proceedLock( token, withdrawer, amountToLock, unlockTime, crxToLock, true ); } /** * @notice token vesting * @param token token address to lock * @param amount overall amount of tokens to lock * @param percents[] array of amount percentage (1e4 = 100%). Sum must be 100% * @param unlockTimes[] sorted array of unix times in seconds, must be same length as percents[] * @param withdrawer account that can withdraw tokens to it's balance * @param feePaymentMode 0 - pay fees in ETH + % of token, * 1 - pay fees in CRX + % of token, * 2 - pay fees fully in BNB, * 3 - pay fees fully in CRX * 4 - pay fees by locking CRX * @param referrer account of referrer */ function vestTokens( address token, uint256 amount, uint256[] memory percents, uint256[] memory unlockTimes, address payable withdrawer, uint8 feePaymentMode, address referrer ) external payable nonReentrant { require(percents.length == unlockTimes.length, "ARRAY SIZES MISMATCH"); require(percents.length >= 2, "LOW LOCKS COUNT"); require(amount > 0, "ZERO AMOUNT"); require(withdrawer != address(0), "ZERO WITHDRAWER"); require( unlockTimes[0] > block.timestamp + minimalLockTime, "TOO SMALL UNLOCK TIME" ); require( unlockTimes[unlockTimes.length - 1] < 10000000000, "INVALID UNLOCK TIME, MUST BE UNIX TIME IN SECONDS" ); (uint256 amountToLockTotal, uint256 crxToLockTotal) = _getLockAmounts( token, amount, unlockTimes[unlockTimes.length - 1], feePaymentMode, referrer ); uint256 percentsOverall; uint256 amountToLockRest = amountToLockTotal; uint256 crxToLockRest = crxToLockTotal; for (uint256 i = 0; i < unlockTimes.length; ++i) { percentsOverall += percents[i]; uint256 amountToLockNow; uint256 crxToLockNow; if (i < unlockTimes.length - 1) { require( unlockTimes[i] < unlockTimes[i + 1], "UNSORTED UNLOCK TIMES" ); amountToLockNow = amountToLockTotal.mul(percents[i]).div(1e4); crxToLockNow = crxToLockTotal.mul(percents[i]).div(1e4); amountToLockRest -= amountToLockNow; crxToLockRest -= crxToLockNow; } else { amountToLockNow = amountToLockRest; crxToLockNow = crxToLockRest; } _proceedLock( token, withdrawer, amountToLockNow, unlockTimes[i], crxToLockNow, i == 0 ); } require(percentsOverall == 1e4, "INVALID PERCENTS"); } /** * @notice sets new contract to calculate fees * @param newFeesCalculator address of new fees calculator contract */ function setFeesCalculator(address newFeesCalculator) external onlyOwner { require(newFeesCalculator != address(0), "ZERO ADDRESS"); address oldFeesCalculator = address(feesCalculator); feesCalculator = IFeesCalculator(newFeesCalculator); emit OnFeesCalculatorUpdate(oldFeesCalculator, newFeesCalculator); } /** * @notice sets new beneficiary * @param newFeeReceiver address of new fees receiver */ function setFeeReceiver(address payable newFeeReceiver) external onlyOwner { require(newFeeReceiver != address(0), "ZERO ADDRESS"); address lastFeeReceiver = feeReceiver; feeReceiver = newFeeReceiver; emit OnFeeReceiverUpdate(lastFeeReceiver, newFeeReceiver); } /** * @notice initialize fee token * @param _feeToken address of fee token */ function setFeeTokenAddress(address _feeToken) external onlyOwner { require(address(feeToken) == address(0), "already set"); feeToken = IERC20(_feeToken); emit OnFeeTokenUpdate(_feeToken); } /** * @notice sets new minimal lock time * @param newMinimalLockTime address of new fees receiver */ function setMinimalLockTime(uint256 newMinimalLockTime) external onlyOwner { uint256 oldMinimalLockTime = minimalLockTime; minimalLockTime = newMinimalLockTime; emit OnMinimalLockTimeChange(oldMinimalLockTime, newMinimalLockTime); } function website() external pure returns (string memory) { return "https://cryptexlock.me"; } function _proceedLock( address token, address withdrawer, uint256 amountToLock, uint256 unlockTime, uint256 crxToLock, bool needToCheck ) internal virtual returns (uint256 lockId); function _getLockAmounts( address token, uint256 amount, uint256 unlockTime, uint8 feePaymentMode, address referrer ) private returns (uint256 amountToLock, uint256 crxToLock) { ( uint256 ethFee, uint256 systemTokenFee, uint256 tokenFee, uint256 crxLockAmount, uint256 refPercentScaled ) = feesCalculator.calculateFees( token, amount, unlockTime, feePaymentMode, referrer, msg.sender ); require(tokenFee <= amount.div(100), "TOKEN FEE EXCEEDS 1%"); //safeguard for token fee _transferFees( token, ethFee, systemTokenFee, tokenFee, crxLockAmount, referrer, refPercentScaled ); if (msg.value > ethFee) { // transfer excess back _transferBnb(msg.sender, msg.value.sub(ethFee)); } return (amount.sub(tokenFee), crxLockAmount); } function _getIncreaseLockAmounts( address token, uint256 amount, uint256 unlockTime, uint8 feePaymentMode ) internal returns (uint256 actualIncrementAmount, uint256 crxToLock) { ( uint256 ethFee, uint256 systemTokenFee, uint256 tokenFee, uint256 crxLockAmount ) = feesCalculator.calculateIncreaseAmountFees( token, amount, unlockTime, feePaymentMode, msg.sender ); require(tokenFee <= amount.div(100), "TOKEN FEE EXCEEDS 1%"); //safeguard for token fee _transferFees( token, ethFee, systemTokenFee, tokenFee, crxLockAmount, address(0), 0 ); if (msg.value > ethFee) { // transfer excess back _transferBnb(msg.sender, msg.value.sub(ethFee)); } return (amount.sub(tokenFee), crxLockAmount); } function _transferFees( address token, uint256 ethFee, uint256 systemTokenFee, uint256 tokenFee, uint256 crxLockAmount, address referrer, uint256 referralPercentScaled ) internal { address _feeReceiver = feeReceiver; IERC20 _feeToken = feeToken; if (ethFee > 0) { require(msg.value >= ethFee, "ETH FEES NOT MET"); if (referrer != address(0) && referralPercentScaled > 0) { uint256 referralFee = ethFee.mul(referralPercentScaled).div( 1e4 ); _transferBnb(referrer, referralFee); _transferBnb(_feeReceiver, ethFee.sub(referralFee)); } else { _transferBnb(_feeReceiver, ethFee); } } if (systemTokenFee > 0) { require( address(_feeToken) != address(0), "TOKEN FEE TYPE NOT SUPPORTED" ); require( _feeToken.allowance(msg.sender, address(this)) >= systemTokenFee, "TOKEN FEE NOT MET" ); if (referrer != address(0) && referralPercentScaled > 0) { uint256 referralFee = systemTokenFee .mul(referralPercentScaled) .div(1e4); _feeToken.safeTransferFrom(msg.sender, referrer, referralFee); _feeToken.safeTransferFrom( msg.sender, _feeReceiver, systemTokenFee.sub(referralFee) ); } else { _feeToken.safeTransferFrom( msg.sender, _feeReceiver, systemTokenFee ); } } if (tokenFee > 0) { require( IERC20(token).allowance(msg.sender, address(this)) >= tokenFee, "LP TOKEN FEE NOT MET" ); IERC20(token).safeTransferFrom(msg.sender, _feeReceiver, tokenFee); } if (crxLockAmount > 0) { require( address(_feeToken) != address(0), "TOKEN FEE TYPE NOT SUPPORTED" ); _feeToken.safeTransferFrom( msg.sender, address(this), crxLockAmount ); } } function _transferBnb(address recipient, uint256 amount) private { (bool res, ) = recipient.call{value: amount}(""); require(res, "BNB TRANSFER FAILED"); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } }
{ "optimizer": { "enabled": false, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address[]","name":"supportedFactories","type":"address[]"},{"internalType":"address","name":"_feesCalculator","type":"address"},{"internalType":"address payable","name":"_feesReceiver","type":"address"},{"internalType":"address","name":"_feeToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"lastFeeReceiver","type":"address"},{"indexed":false,"internalType":"address","name":"newFeeReceiver","type":"address"}],"name":"OnFeeReceiverUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newAddress","type":"address"}],"name":"OnFeeTokenUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"lastFeesCalculator","type":"address"},{"indexed":false,"internalType":"address","name":"newFeesCalculator","type":"address"}],"name":"OnFeesCalculatorUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"lockId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"OnLockAmountIncreased","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"lockId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newUnlockTime","type":"uint256"}],"name":"OnLockDurationIncreased","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"lockId","type":"uint256"},{"indexed":true,"internalType":"address","name":"migrator","type":"address"}],"name":"OnLockMigration","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"lockId","type":"uint256"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OnLockOwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"lockId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"OnLockWithdrawal","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldMinimalLockTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMinimalLockTime","type":"uint256"}],"name":"OnMinimalLockTimeChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"lockId","type":"uint256"},{"indexed":true,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"unlockTime","type":"uint256"}],"name":"OnTokenLock","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"lockId","type":"uint256"}],"name":"OnTokenUnlock","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"uint256","name":"lockId","type":"uint256"},{"internalType":"uint256","name":"newUnlockTime","type":"uint256"}],"name":"extendLockTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeReceiver","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feesCalculator","outputs":[{"internalType":"contract IFeesCalculator","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"lockId","type":"uint256"},{"internalType":"uint256","name":"amountToIncrement","type":"uint256"},{"internalType":"uint8","name":"feePaymentMode","type":"uint8"}],"name":"increaseLockAmount","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isFactorySupported","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"unlockTime","type":"uint256"},{"internalType":"address payable","name":"withdrawer","type":"address"},{"internalType":"uint8","name":"feePaymentMode","type":"uint8"},{"internalType":"address","name":"referrer","type":"address"}],"name":"lockTokens","outputs":[{"internalType":"uint256","name":"lockId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"lockId","type":"uint256"},{"internalType":"address","name":"migratorContract","type":"address"}],"name":"migrate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"migrator","outputs":[{"internalType":"contract IMigrator","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minimalLockTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"recoverLockedTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"newFeeReceiver","type":"address"}],"name":"setFeeReceiver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeToken","type":"address"}],"name":"setFeeTokenAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newFeesCalculator","type":"address"}],"name":"setFeesCalculator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"factory","type":"address"},{"internalType":"bool","name":"value","type":"bool"}],"name":"setIsFactorySupported","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newMigrator","type":"address"}],"name":"setMigrator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMinimalLockTime","type":"uint256"}],"name":"setMinimalLockTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenLocks","outputs":[{"internalType":"address","name":"lpToken","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"tokenAmount","type":"uint256"},{"internalType":"uint256","name":"unlockTime","type":"uint256"},{"internalType":"uint256","name":"lockedCrx","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"lockId","type":"uint256"},{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferLock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"userLockAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"userLocksLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256[]","name":"percents","type":"uint256[]"},{"internalType":"uint256[]","name":"unlockTimes","type":"uint256[]"},{"internalType":"address payable","name":"withdrawer","type":"address"},{"internalType":"uint8","name":"feePaymentMode","type":"uint8"},{"internalType":"address","name":"referrer","type":"address"}],"name":"vestTokens","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"website","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"lockId","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"lockId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawPartially","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b5060405162005fc738038062005fc7833981810160405260808110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b838201915060208201858111156200006f57600080fd5b82518660208202830111640100000000821117156200008d57600080fd5b8083526020830192505050908051906020019060200280838360005b83811015620000c6578082015181840152602081019050620000a9565b50505050905001604052602001805190602001909291908051906020019092919080519060200190929190505050600160008190555060006200010e6200048360201b60201c565b905080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35082600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060005b8451811015620004785760006001820190505b855181101562000367578581815181106200029d57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff16868381518110620002c857fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614156200035b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f57524f4e4720464143544f52494553000000000000000000000000000000000081525060200191505060405180910390fd5b80600101905062000286565b506200038d8582815181106200037957fe5b60200260200101516200048b60201b60201c565b62000400576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f57524f4e4720464143544f52494553000000000000000000000000000000000081525060200191505060405180910390fd5b6001600760008784815181106200041357fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555080600101905062000273565b5050505050620005a7565b600033905090565b6000620004b98273ffffffffffffffffffffffffffffffffffffffff166200059460201b62003aa71760201c565b620004c857600090506200058f565b8173ffffffffffffffffffffffffffffffffffffffff1663574f2ba36040518163ffffffff1660e01b815260040160206040518083038186803b1580156200050f57600080fd5b505afa9250505080156200054557506040513d60208110156200053157600080fd5b810190808051906020019092919050505060015b62000589573d806000811462000578576040519150601f19603f3d011682016040523d82523d6000602084013e6200057d565b606091505b5060009150506200058f565b60019150505b919050565b600080823b905060008111915050919050565b615a1080620005b76000396000f3fe6080604052600436106101b75760003560e01c80637cd07e47116100ec578063b6fffbf01161008a578063cf351c1d11610064578063cf351c1d14610b31578063dab03b1914610b82578063efdcd97414610bbd578063f2fde38b14610c0e576101b7565b8063b6fffbf0146109f7578063beb0a41614610a3c578063c28aa3d814610acc576101b7565b8063a4a99b69116100c6578063a4a99b69146108d1578063a695585714610916578063b3f006741461095b578063b48dd3be1461099c576101b7565b80637cd07e47146107b85780638da5cb5b146107f9578063946ca9491461083a576101b7565b8063405b84fa11610159578063647846a511610133578063647846a5146106e45780636c71564114610725578063715018a6146107765780637c5eb9401461078d576101b7565b8063405b84fa1461045f57806359f7545d146104ba578063639a810c1461067d576101b7565b806324e2a8211161019557806324e2a8211461032357806328a2e7f0146103925780632e1a7d4d146103e357806335a03bfa1461041e576101b7565b80630dd60c70146101bc5780630ff9c22f1461027557806323cf3118146102d2575b600080fd5b61025f600480360360c08110156101d257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803560ff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610c5f565b6040518082815260200191505060405180910390f35b34801561028157600080fd5b506102d06004803603604081101561029857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803515159060200190929190505050610fad565b005b3480156102de57600080fd5b50610321600480360360208110156102f557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611132565b005b34801561032f57600080fd5b5061037c6004803603604081101561034657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611225565b6040518082815260200191505060405180910390f35b34801561039e57600080fd5b506103e1600480360360208110156103b557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611280565b005b3480156103ef57600080fd5b5061041c6004803603602081101561040657600080fd5b8101908080359060200190929190505050611487565b005b34801561042a57600080fd5b506104336114b0565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561046b57600080fd5b506104b86004803603604081101561048257600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506114d6565b005b61067b600480360360e08110156104d057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561051757600080fd5b82018360208201111561052957600080fd5b8035906020019184602083028401116401000000008311171561054b57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050509192919290803590602001906401000000008111156105ab57600080fd5b8201836020820111156105bd57600080fd5b803590602001918460208302840111640100000000831117156105df57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050509192919290803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803560ff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611ab6565b005b34801561068957600080fd5b506106cc600480360360208110156106a057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612095565b60405180821515815260200191505060405180910390f35b3480156106f057600080fd5b506106f96120b5565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561073157600080fd5b506107746004803603602081101561074857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506120db565b005b34801561078257600080fd5b5061078b612304565b005b34801561079957600080fd5b506107a2612474565b6040518082815260200191505060405180910390f35b3480156107c457600080fd5b506107cd61247a565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561080557600080fd5b5061080e6124a0565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561084657600080fd5b506108736004803603602081101561085d57600080fd5b81019080803590602001909291905050506124ca565b604051808673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018381526020018281526020019550505050505060405180910390f35b610914600480360360608110156108e757600080fd5b810190808035906020019092919080359060200190929190803560ff169060200190929190505050612540565b005b34801561092257600080fd5b506109596004803603604081101561093957600080fd5b810190808035906020019092919080359060200190929190505050612821565b005b34801561096757600080fd5b50610970612cd5565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156109a857600080fd5b506109f5600480360360408110156109bf57600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612cfb565b005b348015610a0357600080fd5b50610a3a60048036036040811015610a1a57600080fd5b810190808035906020019092919080359060200190929190505050612fe8565b005b348015610a4857600080fd5b50610a516132f8565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610a91578082015181840152602081019050610a76565b50505050905090810190601f168015610abe5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b348015610ad857600080fd5b50610b1b60048036036020811015610aef57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613335565b6040518082815260200191505060405180910390f35b348015610b3d57600080fd5b50610b8060048036036020811015610b5457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613385565b005b348015610b8e57600080fd5b50610bbb60048036036020811015610ba557600080fd5b8101908080359060200190929190505050613589565b005b348015610bc957600080fd5b50610c0c60048036036020811015610be057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613689565b005b348015610c1a57600080fd5b50610c5d60048036036020811015610c3157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506138b2565b005b600060026000541415610cda576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b600260008190555060008611610d58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600b8152602001807f5a45524f20414d4f554e5400000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff161415610dfb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f5a45524f20544f4b454e0000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415610e9e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f5a45524f2057495448445241574552000000000000000000000000000000000081525060200191505060405180910390fd5b6402540be4008510610efb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260318152602001806159296031913960400191505060405180910390fd5b60055442018511610f74576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f544f4f20534d414c4c20554e4c4f434b2054494d45000000000000000000000081525060200191505060405180910390fd5b600080610f848989898888613aba565b91509150610f978987848a856001613cf6565b9250505060016000819055509695505050505050565b610fb5613f9f565b73ffffffffffffffffffffffffffffffffffffffff16610fd36124a0565b73ffffffffffffffffffffffffffffffffffffffff161461105c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b61106582613fa7565b6110d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f57524f4e4720464143544f52590000000000000000000000000000000000000081525060200191505060405180910390fd5b80600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b61113a613f9f565b73ffffffffffffffffffffffffffffffffffffffff166111586124a0565b73ffffffffffffffffffffffffffffffffffffffff16146111e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b80600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600061127882600a60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061409a90919063ffffffff16565b905092915050565b611288613f9f565b73ffffffffffffffffffffffffffffffffffffffff166112a66124a0565b73ffffffffffffffffffffffffffffffffffffffff161461132f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b611338816140b4565b156113ab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f756e61626c6520746f207265636f766572204c5020746f6b656e00000000000081525060200191505060405180910390fd5b60008190506114836113bb6124a0565b8273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561142257600080fd5b505afa158015611436573d6000803e3d6000fd5b505050506040513d602081101561144c57600080fd5b81019080805190602001909291905050508373ffffffffffffffffffffffffffffffffffffffff166144039092919063ffffffff16565b5050565b60006009600083815260200190815260200160002090506114ac828260020154612821565b5050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6002600054141561154f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b6002600081905550600073ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141561161c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600b8152602001807f4e4f204d49475241544f5200000000000000000000000000000000000000000081525060200191505060405180910390fd5b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146116df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f57524f4e47204d49475241544f5200000000000000000000000000000000000081525060200191505060405180910390fd5b60006009600084815260200190815260200160002090503373ffffffffffffffffffffffffffffffffffffffff168160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146117bb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f4f4e4c59204c4f434b204f574e4552000000000000000000000000000000000081525060200191505060405180910390fd5b611830600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1682600201548360000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166144a59092919063ffffffff16565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663db5ecd3f8260000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836002015484600301548560010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518563ffffffff1660e01b8152600401808573ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff168152602001945050505050600060405180830381600087803b15801561193957600080fd5b505af115801561194d573d6000803e3d6000fd5b50505050600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16837f0bef3dfd2c699190b6fbc19bd6141032806b257965fe4fd1fb461d4712d2e12960405160405180910390a3611a2c83600a60008460010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061466a90919063ffffffff16565b5060096000848152602001908152602001600020600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905560028201600090556003820160009055600482016000905550505060016000819055505050565b60026000541415611b2f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b60026000819055508351855114611bae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f41525241592053495a4553204d49534d4154434800000000000000000000000081525060200191505060405180910390fd5b600285511015611c26576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f4c4f57204c4f434b5320434f554e54000000000000000000000000000000000081525060200191505060405180910390fd5b60008611611c9c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600b8152602001807f5a45524f20414d4f554e5400000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611d3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f5a45524f2057495448445241574552000000000000000000000000000000000081525060200191505060405180910390fd5b600554420184600081518110611d5157fe5b602002602001015111611dcc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f544f4f20534d414c4c20554e4c4f434b2054494d45000000000000000000000081525060200191505060405180910390fd5b6402540be40084600186510381518110611de257fe5b602002602001015110611e40576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260318152602001806159296031913960400191505060405180910390fd5b600080611e6789898860018a510381518110611e5857fe5b60200260200101518787613aba565b91509150600080839050600083905060005b8951811015612007578a8181518110611e8e57fe5b60200260200101518401935060008060018c5103831015611fce578b6001840181518110611eb857fe5b60200260200101518c8481518110611ecc57fe5b602002602001015110611f47576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f554e534f5254454420554e4c4f434b2054494d4553000000000000000000000081525060200191505060405180910390fd5b611f81612710611f738f8681518110611f5c57fe5b60200260200101518b61468490919063ffffffff16565b61470a90919063ffffffff16565b9150611fbd612710611faf8f8681518110611f9857fe5b60200260200101518a61468490919063ffffffff16565b61470a90919063ffffffff16565b905081850394508084039350611fd5565b8491508390505b611ff98f8c848f8781518110611fe757fe5b60200260200101518560008914613cf6565b505050806001019050611e79565b50612710831461207f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f494e56414c49442050455243454e54530000000000000000000000000000000081525060200191505060405180910390fd5b5050505050600160008190555050505050505050565b60076020528060005260406000206000915054906101000a900460ff1681565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6120e3613f9f565b73ffffffffffffffffffffffffffffffffffffffff166121016124a0565b73ffffffffffffffffffffffffffffffffffffffff161461218a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561222d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f5a45524f2041444452455353000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f5035b14f394ce553986932cb1f36cde25bdad4c1a79d071c4405ebe7bb8328cc8183604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a15050565b61230c613f9f565b73ffffffffffffffffffffffffffffffffffffffff1661232a6124a0565b73ffffffffffffffffffffffffffffffffffffffff16146123b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60055481565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60096020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154908060030154908060040154905085565b600260005414156125b9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b60026000819055508260006009600083815260200190815260200160002090503373ffffffffffffffffffffffffffffffffffffffff168160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461269e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f4e4f20414354495645204c4f434b204f52204e4f54204f574e4552000000000081525060200191505060405180910390fd5b60008411612714576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600b8152602001807f5a45524f20414d4f554e5400000000000000000000000000000000000000000081525060200191505060405180910390fd5b600060096000878152602001908152602001600020905060008160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600080612767838986600301548a614793565b915091506127828285600201546149a290919063ffffffff16565b84600201819055506127a18185600401546149a290919063ffffffff16565b84600401819055506127d63330848673ffffffffffffffffffffffffffffffffffffffff16614a2a909392919063ffffffff16565b887f726a87743148b6d1e89b17e740a496a48f2515cab6794def6e92b1765b773a6a896040518082815260200191505060405180910390a25050505050506001600081905550505050565b6002600054141561289a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b60026000819055508160006009600083815260200190815260200160002090503373ffffffffffffffffffffffffffffffffffffffff168160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461297f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f4e4f20414354495645204c4f434b204f52204e4f54204f574e4552000000000081525060200191505060405180910390fd5b60006009600086815260200190815260200160002090508381600201541015612a10576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f414d4f554e542045584345454453204c4f434b4544000000000000000000000081525060200191505060405180910390fd5b8060030154421015612a8a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f4e4f542059455420554e4c4f434b45440000000000000000000000000000000081525060200191505060405180910390fd5b60008160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050612b0281868460000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166144039092919063ffffffff16565b6000612b1b868460020154614aeb90919063ffffffff16565b90508083600201819055506000811415612c8c576000836004015490506000811115612b8f57612b8e8382600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166144039092919063ffffffff16565b5b612be088600a60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061466a90919063ffffffff16565b5060096000898152602001908152602001600020600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556002820160009055600382016000905560048201600090555050877f474ad196311b1b95407b51dc0515179f4a588c875f35e1d5b4a2d963e6cdd79160405160405180910390a2505b867f4741c0a61cf65d0435cc6b57d59b9203082089e8911228f3b6b0031cc2e95b91876040518082815260200191505060405180910390a2505050505060016000819055505050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b8160006009600083815260200190815260200160002090503373ffffffffffffffffffffffffffffffffffffffff168160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612dd8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f4e4f20414354495645204c4f434b204f52204e4f54204f574e4552000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415612e7b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f5a45524f204e4557204f574e455200000000000000000000000000000000000081525060200191505060405180910390fd5b6000600960008681526020019081526020016000209050612f0785600a60008460010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061466a90919063ffffffff16565b50612f5985600a60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020614b6e90919063ffffffff16565b50838160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508373ffffffffffffffffffffffffffffffffffffffff16857ffd9536909af70d0956b4cd5199aea8fa73c2c76717d789c3fa99427fca1ebf5960405160405180910390a35050505050565b60026000541415613061576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b60026000819055508160006009600083815260200190815260200160002090503373ffffffffffffffffffffffffffffffffffffffff168160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613146576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f4e4f20414354495645204c4f434b204f52204e4f54204f574e4552000000000081525060200191505060405180910390fd5b4283116131bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f554e4c4f434b2054494d4520494e20544845205041535400000000000000000081525060200191505060405180910390fd5b6402540be4008310613218576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260318152602001806159296031913960400191505060405180910390fd5b6000600960008681526020019081526020016000209050838160030154106132a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f4e4f5420494e4352454153494e4720554e4c4f434b2054494d4500000000000081525060200191505060405180910390fd5b838160030181905550847f9a0a6aaaf60f7e2d9b37efb62343fd4bd400065be75ad75116551ab82aa123ec856040518082815260200191505060405180910390a250505060016000819055505050565b60606040518060400160405280601681526020017f68747470733a2f2f637279707465786c6f636b2e6d6500000000000000000000815250905090565b600061337e600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020614b88565b9050919050565b61338d613f9f565b73ffffffffffffffffffffffffffffffffffffffff166133ab6124a0565b73ffffffffffffffffffffffffffffffffffffffff1614613434576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146134f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600b8152602001807f616c72656164792073657400000000000000000000000000000000000000000081525060200191505060405180910390fd5b80600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fe036741a59ec0d11dc644db37c368902dbacee321a73534e1bfae9d8f4c920ff81604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b613591613f9f565b73ffffffffffffffffffffffffffffffffffffffff166135af6124a0565b73ffffffffffffffffffffffffffffffffffffffff1614613638576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60006005549050816005819055507ff938e21968206ac822db3ed3ee9de49c901dfb545aa6cf69d23945af0f92ad118183604051808381526020018281526020019250505060405180910390a15050565b613691613f9f565b73ffffffffffffffffffffffffffffffffffffffff166136af6124a0565b73ffffffffffffffffffffffffffffffffffffffff1614613738576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156137db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f5a45524f2041444452455353000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f940dc4f308f0f1d81134ebdcd4f6118aee6310860254e7621ee421d9f6d271cb8183604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a15050565b6138ba613f9f565b73ffffffffffffffffffffffffffffffffffffffff166138d86124a0565b73ffffffffffffffffffffffffffffffffffffffff1614613961576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156139e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806158dd6026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080823b905060008111915050919050565b6000806000806000806000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dc7595978d8d8d8d8d336040518763ffffffff1660e01b8152600401808773ffffffffffffffffffffffffffffffffffffffff1681526020018681526020018581526020018460ff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff168152602001965050505050505060a06040518083038186803b158015613ba557600080fd5b505afa158015613bb9573d6000803e3d6000fd5b505050506040513d60a0811015613bcf57600080fd5b81019080805190602001909291908051906020019092919080519060200190929190805190602001909291908051906020019092919050505094509450945094509450613c2660648c61470a90919063ffffffff16565b831115613c9b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f544f4b454e20464545204558434545445320312500000000000000000000000081525060200191505060405180910390fd5b613caa8c868686868d87614b9d565b84341115613ccf57613cce33613cc98734614aeb90919063ffffffff16565b61524f565b5b613ce2838c614aeb90919063ffffffff16565b829650965050505050509550959350505050565b60008115613d7a57613d07876140b4565b613d79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4e4f54204445582050414952000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b60006040518060a001604052808973ffffffffffffffffffffffffffffffffffffffff1681526020018873ffffffffffffffffffffffffffffffffffffffff16815260200187815260200186815260200185815250905060066000815480929190600101919050559150806009600084815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550604082015181600201556060820151816003015560808201518160040155905050613ef882600a60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020614b6e90919063ffffffff16565b50613f263330888b73ffffffffffffffffffffffffffffffffffffffff16614a2a909392919063ffffffff16565b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff16837f601e52fd7ec7840490f1ae9c376bc3b32f6a6a6aac8dc10db76d87ef0fa45d328989604051808381526020018281526020019250505060405180910390a4509695505050505050565b600033905090565b6000613fc88273ffffffffffffffffffffffffffffffffffffffff16613aa7565b613fd55760009050614095565b8173ffffffffffffffffffffffffffffffffffffffff1663574f2ba36040518163ffffffff1660e01b815260040160206040518083038186803b15801561401b57600080fd5b505afa92505050801561404f57506040513d602081101561403b57600080fd5b810190808051906020019092919050505060015b61408f573d806000811461407f576040519150601f19603f3d011682016040523d82523d6000602084013e614084565b606091505b506000915050614095565b60019150505b919050565b60006140a98360000183615330565b60001c905092915050565b60006140d58273ffffffffffffffffffffffffffffffffffffffff16613aa7565b6140e257600090506143fe565b600082905060008173ffffffffffffffffffffffffffffffffffffffff1663c45a01556040518163ffffffff1660e01b815260040160206040518083038186803b15801561412f57600080fd5b505afa92505050801561416357506040513d602081101561414f57600080fd5b810190808051906020019092919050505060015b6141a5573d8060008114614193576040519150601f19603f3d011682016040523d82523d6000602084013e614198565b606091505b50600093505050506143fe565b80915050600760008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16614205576000925050506143fe565b60008173ffffffffffffffffffffffffffffffffffffffff1663e6a439058473ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b15801561426957600080fd5b505afa15801561427d573d6000803e3d6000fd5b505050506040513d602081101561429357600080fd5b81019080805190602001909291905050508573ffffffffffffffffffffffffffffffffffffffff1663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b1580156142ea57600080fd5b505afa1580156142fe573d6000803e3d6000fd5b505050506040513d602081101561431457600080fd5b81019080805190602001909291905050506040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b15801561438c57600080fd5b505afa1580156143a0573d6000803e3d6000fd5b505050506040513d60208110156143b657600080fd5b810190808051906020019092919050505090508473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161493505050505b919050565b6144a08363a9059cbb60e01b8484604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506153b3565b505050565b6000811480614573575060008373ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e30856040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b15801561453657600080fd5b505afa15801561454a573d6000803e3d6000fd5b505050506040513d602081101561456057600080fd5b8101908080519060200190929190505050145b6145c8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001806159a56036913960400191505060405180910390fd5b6146658363095ea7b360e01b8484604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506153b3565b505050565b600061467c836000018360001b6154a2565b905092915050565b6000808314156146975760009050614704565b60008284029050828482816146a857fe5b04146146ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602181526020018061595a6021913960400191505060405180910390fd5b809150505b92915050565b6000808211614781576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525060200191505060405180910390fd5b81838161478a57fe5b04905092915050565b600080600080600080600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ca1556c18b8b8b8b336040518663ffffffff1660e01b8152600401808673ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018481526020018360ff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019550505050505060806040518083038186803b15801561485e57600080fd5b505afa158015614872573d6000803e3d6000fd5b505050506040513d608081101561488857600080fd5b810190808051906020019092919080519060200190929190805190602001909291908051906020019092919050505093509350935093506148d360648a61470a90919063ffffffff16565b821115614948576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f544f4b454e20464545204558434545445320312500000000000000000000000081525060200191505060405180910390fd5b6149588a85858585600080614b9d565b8334111561497d5761497c336149778634614aeb90919063ffffffff16565b61524f565b5b614990828a614aeb90919063ffffffff16565b81955095505050505094509492505050565b600080828401905083811015614a20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b614ae5846323b872dd60e01b858585604051602401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506153b3565b50505050565b600082821115614b63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060200191505060405180910390fd5b818303905092915050565b6000614b80836000018360001b61558a565b905092915050565b6000614b96826000016155fa565b9050919050565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506000881115614d0f5787341015614c6a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f4554482046454553204e4f54204d45540000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614158015614ca75750600083115b15614d03576000614cd5612710614cc7868c61468490919063ffffffff16565b61470a90919063ffffffff16565b9050614ce1858261524f565b614cfd83614cf8838c614aeb90919063ffffffff16565b61524f565b50614d0e565b614d0d828961524f565b5b5b6000871115614ffe57600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415614dbb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f544f4b454e204645452054595045204e4f5420535550504f525445440000000081525060200191505060405180910390fd5b868173ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e33306040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b158015614e4157600080fd5b505afa158015614e55573d6000803e3d6000fd5b505050506040513d6020811015614e6b57600080fd5b81019080805190602001909291905050501015614ef0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f544f4b454e20464545204e4f54204d455400000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614158015614f2d5750600083115b15614fcf576000614f5b612710614f4d868b61468490919063ffffffff16565b61470a90919063ffffffff16565b9050614f8a3386838573ffffffffffffffffffffffffffffffffffffffff16614a2a909392919063ffffffff16565b614fc93384614fa2848c614aeb90919063ffffffff16565b8573ffffffffffffffffffffffffffffffffffffffff16614a2a909392919063ffffffff16565b50614ffd565b614ffc3383898473ffffffffffffffffffffffffffffffffffffffff16614a2a909392919063ffffffff16565b5b5b600086111561516a57858973ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e33306040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b15801561508d57600080fd5b505afa1580156150a1573d6000803e3d6000fd5b505050506040513d60208110156150b757600080fd5b8101908080519060200190929190505050101561513c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f4c5020544f4b454e20464545204e4f54204d455400000000000000000000000081525060200191505060405180910390fd5b6151693383888c73ffffffffffffffffffffffffffffffffffffffff16614a2a909392919063ffffffff16565b5b600085111561524457600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415615216576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f544f4b454e204645452054595045204e4f5420535550504f525445440000000081525060200191505060405180910390fd5b6152433330878473ffffffffffffffffffffffffffffffffffffffff16614a2a909392919063ffffffff16565b5b505050505050505050565b60008273ffffffffffffffffffffffffffffffffffffffff168260405180600001905060006040518083038185875af1925050503d80600081146152af576040519150601f19603f3d011682016040523d82523d6000602084013e6152b4565b606091505b505090508061532b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f424e42205452414e53464552204641494c45440000000000000000000000000081525060200191505060405180910390fd5b505050565b600081836000018054905011615391576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806158bb6022913960400191505060405180910390fd5b8260000182815481106153a057fe5b9060005260206000200154905092915050565b6000615415826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661560b9092919063ffffffff16565b905060008151111561549d5780806020019051602081101561543657600080fd5b810190808051906020019092919050505061549c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a81526020018061597b602a913960400191505060405180910390fd5b5b505050565b6000808360010160008481526020019081526020016000205490506000811461557e57600060018203905060006001866000018054905003905060008660000182815481106154ed57fe5b906000526020600020015490508087600001848154811061550a57fe5b906000526020600020018190555060018301876001016000838152602001908152602001600020819055508660000180548061554257fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050615584565b60009150505b92915050565b60006155968383615623565b6155ef5782600001829080600181540180825580915050600190039060005260206000200160009091909190915055826000018054905083600101600084815260200190815260200160002081905550600190506155f4565b600090505b92915050565b600081600001805490509050919050565b606061561a8484600085615646565b90509392505050565b600080836001016000848152602001908152602001600020541415905092915050565b6060824710156156a1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806159036026913960400191505060405180910390fd5b6156aa85613aa7565b61571c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b6020831061576b5780518252602082019150602081019050602083039250615748565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146157cd576040519150601f19603f3d011682016040523d82523d6000602084013e6157d2565b606091505b50915091506157e28282866157ee565b92505050949350505050565b606083156157fe578290506158b3565b6000835111156158115782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561587857808201518184015260208101905061585d565b50505050905090810190601f1680156158a55780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b939250505056fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e64734f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c494e56414c494420554e4c4f434b2054494d452c204d55535420424520554e49582054494d4520494e205345434f4e4453536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565645361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f20746f206e6f6e2d7a65726f20616c6c6f77616e6365a2646970667358221220791a9d2f847c1e920755b1ab60ee31cda91f9f0cba422017a344046443bbe62064736f6c63430007060033000000000000000000000000000000000000000000000000000000000000008000000000000000000000000085c76d5b4ce267afdfc24d6022262dcf9f0c4f4d000000000000000000000000e92651c0a980f60a7f352a4cbb06e8a429876d2400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000152ee697f2e276fa89e96742e9bb9ab1f2e61be3000000000000000000000000ef45d134b73241eda7703fa787148d9c9f4950b0000000000000000000000000d9473a05b2edf4f614593ba5d1dbd3021d8e0ebe0000000000000000000000007d82f56ea0820a9d42b01c3c28f1997721732218
Deployed Bytecode
0x6080604052600436106101b75760003560e01c80637cd07e47116100ec578063b6fffbf01161008a578063cf351c1d11610064578063cf351c1d14610b31578063dab03b1914610b82578063efdcd97414610bbd578063f2fde38b14610c0e576101b7565b8063b6fffbf0146109f7578063beb0a41614610a3c578063c28aa3d814610acc576101b7565b8063a4a99b69116100c6578063a4a99b69146108d1578063a695585714610916578063b3f006741461095b578063b48dd3be1461099c576101b7565b80637cd07e47146107b85780638da5cb5b146107f9578063946ca9491461083a576101b7565b8063405b84fa11610159578063647846a511610133578063647846a5146106e45780636c71564114610725578063715018a6146107765780637c5eb9401461078d576101b7565b8063405b84fa1461045f57806359f7545d146104ba578063639a810c1461067d576101b7565b806324e2a8211161019557806324e2a8211461032357806328a2e7f0146103925780632e1a7d4d146103e357806335a03bfa1461041e576101b7565b80630dd60c70146101bc5780630ff9c22f1461027557806323cf3118146102d2575b600080fd5b61025f600480360360c08110156101d257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803560ff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610c5f565b6040518082815260200191505060405180910390f35b34801561028157600080fd5b506102d06004803603604081101561029857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803515159060200190929190505050610fad565b005b3480156102de57600080fd5b50610321600480360360208110156102f557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611132565b005b34801561032f57600080fd5b5061037c6004803603604081101561034657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611225565b6040518082815260200191505060405180910390f35b34801561039e57600080fd5b506103e1600480360360208110156103b557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611280565b005b3480156103ef57600080fd5b5061041c6004803603602081101561040657600080fd5b8101908080359060200190929190505050611487565b005b34801561042a57600080fd5b506104336114b0565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561046b57600080fd5b506104b86004803603604081101561048257600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506114d6565b005b61067b600480360360e08110156104d057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561051757600080fd5b82018360208201111561052957600080fd5b8035906020019184602083028401116401000000008311171561054b57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050509192919290803590602001906401000000008111156105ab57600080fd5b8201836020820111156105bd57600080fd5b803590602001918460208302840111640100000000831117156105df57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050509192919290803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803560ff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611ab6565b005b34801561068957600080fd5b506106cc600480360360208110156106a057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612095565b60405180821515815260200191505060405180910390f35b3480156106f057600080fd5b506106f96120b5565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561073157600080fd5b506107746004803603602081101561074857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506120db565b005b34801561078257600080fd5b5061078b612304565b005b34801561079957600080fd5b506107a2612474565b6040518082815260200191505060405180910390f35b3480156107c457600080fd5b506107cd61247a565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561080557600080fd5b5061080e6124a0565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561084657600080fd5b506108736004803603602081101561085d57600080fd5b81019080803590602001909291905050506124ca565b604051808673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018381526020018281526020019550505050505060405180910390f35b610914600480360360608110156108e757600080fd5b810190808035906020019092919080359060200190929190803560ff169060200190929190505050612540565b005b34801561092257600080fd5b506109596004803603604081101561093957600080fd5b810190808035906020019092919080359060200190929190505050612821565b005b34801561096757600080fd5b50610970612cd5565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156109a857600080fd5b506109f5600480360360408110156109bf57600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612cfb565b005b348015610a0357600080fd5b50610a3a60048036036040811015610a1a57600080fd5b810190808035906020019092919080359060200190929190505050612fe8565b005b348015610a4857600080fd5b50610a516132f8565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610a91578082015181840152602081019050610a76565b50505050905090810190601f168015610abe5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b348015610ad857600080fd5b50610b1b60048036036020811015610aef57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613335565b6040518082815260200191505060405180910390f35b348015610b3d57600080fd5b50610b8060048036036020811015610b5457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613385565b005b348015610b8e57600080fd5b50610bbb60048036036020811015610ba557600080fd5b8101908080359060200190929190505050613589565b005b348015610bc957600080fd5b50610c0c60048036036020811015610be057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613689565b005b348015610c1a57600080fd5b50610c5d60048036036020811015610c3157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506138b2565b005b600060026000541415610cda576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b600260008190555060008611610d58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600b8152602001807f5a45524f20414d4f554e5400000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff161415610dfb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f5a45524f20544f4b454e0000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415610e9e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f5a45524f2057495448445241574552000000000000000000000000000000000081525060200191505060405180910390fd5b6402540be4008510610efb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260318152602001806159296031913960400191505060405180910390fd5b60055442018511610f74576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f544f4f20534d414c4c20554e4c4f434b2054494d45000000000000000000000081525060200191505060405180910390fd5b600080610f848989898888613aba565b91509150610f978987848a856001613cf6565b9250505060016000819055509695505050505050565b610fb5613f9f565b73ffffffffffffffffffffffffffffffffffffffff16610fd36124a0565b73ffffffffffffffffffffffffffffffffffffffff161461105c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b61106582613fa7565b6110d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f57524f4e4720464143544f52590000000000000000000000000000000000000081525060200191505060405180910390fd5b80600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b61113a613f9f565b73ffffffffffffffffffffffffffffffffffffffff166111586124a0565b73ffffffffffffffffffffffffffffffffffffffff16146111e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b80600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600061127882600a60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061409a90919063ffffffff16565b905092915050565b611288613f9f565b73ffffffffffffffffffffffffffffffffffffffff166112a66124a0565b73ffffffffffffffffffffffffffffffffffffffff161461132f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b611338816140b4565b156113ab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f756e61626c6520746f207265636f766572204c5020746f6b656e00000000000081525060200191505060405180910390fd5b60008190506114836113bb6124a0565b8273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561142257600080fd5b505afa158015611436573d6000803e3d6000fd5b505050506040513d602081101561144c57600080fd5b81019080805190602001909291905050508373ffffffffffffffffffffffffffffffffffffffff166144039092919063ffffffff16565b5050565b60006009600083815260200190815260200160002090506114ac828260020154612821565b5050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6002600054141561154f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b6002600081905550600073ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141561161c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600b8152602001807f4e4f204d49475241544f5200000000000000000000000000000000000000000081525060200191505060405180910390fd5b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146116df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f57524f4e47204d49475241544f5200000000000000000000000000000000000081525060200191505060405180910390fd5b60006009600084815260200190815260200160002090503373ffffffffffffffffffffffffffffffffffffffff168160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146117bb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f4f4e4c59204c4f434b204f574e4552000000000000000000000000000000000081525060200191505060405180910390fd5b611830600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1682600201548360000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166144a59092919063ffffffff16565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663db5ecd3f8260000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836002015484600301548560010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518563ffffffff1660e01b8152600401808573ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff168152602001945050505050600060405180830381600087803b15801561193957600080fd5b505af115801561194d573d6000803e3d6000fd5b50505050600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16837f0bef3dfd2c699190b6fbc19bd6141032806b257965fe4fd1fb461d4712d2e12960405160405180910390a3611a2c83600a60008460010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061466a90919063ffffffff16565b5060096000848152602001908152602001600020600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905560028201600090556003820160009055600482016000905550505060016000819055505050565b60026000541415611b2f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b60026000819055508351855114611bae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f41525241592053495a4553204d49534d4154434800000000000000000000000081525060200191505060405180910390fd5b600285511015611c26576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f4c4f57204c4f434b5320434f554e54000000000000000000000000000000000081525060200191505060405180910390fd5b60008611611c9c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600b8152602001807f5a45524f20414d4f554e5400000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611d3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f5a45524f2057495448445241574552000000000000000000000000000000000081525060200191505060405180910390fd5b600554420184600081518110611d5157fe5b602002602001015111611dcc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f544f4f20534d414c4c20554e4c4f434b2054494d45000000000000000000000081525060200191505060405180910390fd5b6402540be40084600186510381518110611de257fe5b602002602001015110611e40576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260318152602001806159296031913960400191505060405180910390fd5b600080611e6789898860018a510381518110611e5857fe5b60200260200101518787613aba565b91509150600080839050600083905060005b8951811015612007578a8181518110611e8e57fe5b60200260200101518401935060008060018c5103831015611fce578b6001840181518110611eb857fe5b60200260200101518c8481518110611ecc57fe5b602002602001015110611f47576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f554e534f5254454420554e4c4f434b2054494d4553000000000000000000000081525060200191505060405180910390fd5b611f81612710611f738f8681518110611f5c57fe5b60200260200101518b61468490919063ffffffff16565b61470a90919063ffffffff16565b9150611fbd612710611faf8f8681518110611f9857fe5b60200260200101518a61468490919063ffffffff16565b61470a90919063ffffffff16565b905081850394508084039350611fd5565b8491508390505b611ff98f8c848f8781518110611fe757fe5b60200260200101518560008914613cf6565b505050806001019050611e79565b50612710831461207f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f494e56414c49442050455243454e54530000000000000000000000000000000081525060200191505060405180910390fd5b5050505050600160008190555050505050505050565b60076020528060005260406000206000915054906101000a900460ff1681565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6120e3613f9f565b73ffffffffffffffffffffffffffffffffffffffff166121016124a0565b73ffffffffffffffffffffffffffffffffffffffff161461218a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561222d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f5a45524f2041444452455353000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f5035b14f394ce553986932cb1f36cde25bdad4c1a79d071c4405ebe7bb8328cc8183604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a15050565b61230c613f9f565b73ffffffffffffffffffffffffffffffffffffffff1661232a6124a0565b73ffffffffffffffffffffffffffffffffffffffff16146123b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60055481565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60096020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154908060030154908060040154905085565b600260005414156125b9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b60026000819055508260006009600083815260200190815260200160002090503373ffffffffffffffffffffffffffffffffffffffff168160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461269e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f4e4f20414354495645204c4f434b204f52204e4f54204f574e4552000000000081525060200191505060405180910390fd5b60008411612714576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600b8152602001807f5a45524f20414d4f554e5400000000000000000000000000000000000000000081525060200191505060405180910390fd5b600060096000878152602001908152602001600020905060008160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600080612767838986600301548a614793565b915091506127828285600201546149a290919063ffffffff16565b84600201819055506127a18185600401546149a290919063ffffffff16565b84600401819055506127d63330848673ffffffffffffffffffffffffffffffffffffffff16614a2a909392919063ffffffff16565b887f726a87743148b6d1e89b17e740a496a48f2515cab6794def6e92b1765b773a6a896040518082815260200191505060405180910390a25050505050506001600081905550505050565b6002600054141561289a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b60026000819055508160006009600083815260200190815260200160002090503373ffffffffffffffffffffffffffffffffffffffff168160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461297f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f4e4f20414354495645204c4f434b204f52204e4f54204f574e4552000000000081525060200191505060405180910390fd5b60006009600086815260200190815260200160002090508381600201541015612a10576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f414d4f554e542045584345454453204c4f434b4544000000000000000000000081525060200191505060405180910390fd5b8060030154421015612a8a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f4e4f542059455420554e4c4f434b45440000000000000000000000000000000081525060200191505060405180910390fd5b60008160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050612b0281868460000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166144039092919063ffffffff16565b6000612b1b868460020154614aeb90919063ffffffff16565b90508083600201819055506000811415612c8c576000836004015490506000811115612b8f57612b8e8382600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166144039092919063ffffffff16565b5b612be088600a60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061466a90919063ffffffff16565b5060096000898152602001908152602001600020600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556002820160009055600382016000905560048201600090555050877f474ad196311b1b95407b51dc0515179f4a588c875f35e1d5b4a2d963e6cdd79160405160405180910390a2505b867f4741c0a61cf65d0435cc6b57d59b9203082089e8911228f3b6b0031cc2e95b91876040518082815260200191505060405180910390a2505050505060016000819055505050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b8160006009600083815260200190815260200160002090503373ffffffffffffffffffffffffffffffffffffffff168160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612dd8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f4e4f20414354495645204c4f434b204f52204e4f54204f574e4552000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415612e7b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f5a45524f204e4557204f574e455200000000000000000000000000000000000081525060200191505060405180910390fd5b6000600960008681526020019081526020016000209050612f0785600a60008460010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061466a90919063ffffffff16565b50612f5985600a60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020614b6e90919063ffffffff16565b50838160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508373ffffffffffffffffffffffffffffffffffffffff16857ffd9536909af70d0956b4cd5199aea8fa73c2c76717d789c3fa99427fca1ebf5960405160405180910390a35050505050565b60026000541415613061576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b60026000819055508160006009600083815260200190815260200160002090503373ffffffffffffffffffffffffffffffffffffffff168160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613146576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f4e4f20414354495645204c4f434b204f52204e4f54204f574e4552000000000081525060200191505060405180910390fd5b4283116131bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f554e4c4f434b2054494d4520494e20544845205041535400000000000000000081525060200191505060405180910390fd5b6402540be4008310613218576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260318152602001806159296031913960400191505060405180910390fd5b6000600960008681526020019081526020016000209050838160030154106132a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f4e4f5420494e4352454153494e4720554e4c4f434b2054494d4500000000000081525060200191505060405180910390fd5b838160030181905550847f9a0a6aaaf60f7e2d9b37efb62343fd4bd400065be75ad75116551ab82aa123ec856040518082815260200191505060405180910390a250505060016000819055505050565b60606040518060400160405280601681526020017f68747470733a2f2f637279707465786c6f636b2e6d6500000000000000000000815250905090565b600061337e600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020614b88565b9050919050565b61338d613f9f565b73ffffffffffffffffffffffffffffffffffffffff166133ab6124a0565b73ffffffffffffffffffffffffffffffffffffffff1614613434576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146134f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600b8152602001807f616c72656164792073657400000000000000000000000000000000000000000081525060200191505060405180910390fd5b80600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fe036741a59ec0d11dc644db37c368902dbacee321a73534e1bfae9d8f4c920ff81604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b613591613f9f565b73ffffffffffffffffffffffffffffffffffffffff166135af6124a0565b73ffffffffffffffffffffffffffffffffffffffff1614613638576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60006005549050816005819055507ff938e21968206ac822db3ed3ee9de49c901dfb545aa6cf69d23945af0f92ad118183604051808381526020018281526020019250505060405180910390a15050565b613691613f9f565b73ffffffffffffffffffffffffffffffffffffffff166136af6124a0565b73ffffffffffffffffffffffffffffffffffffffff1614613738576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156137db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f5a45524f2041444452455353000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f940dc4f308f0f1d81134ebdcd4f6118aee6310860254e7621ee421d9f6d271cb8183604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a15050565b6138ba613f9f565b73ffffffffffffffffffffffffffffffffffffffff166138d86124a0565b73ffffffffffffffffffffffffffffffffffffffff1614613961576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156139e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806158dd6026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080823b905060008111915050919050565b6000806000806000806000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dc7595978d8d8d8d8d336040518763ffffffff1660e01b8152600401808773ffffffffffffffffffffffffffffffffffffffff1681526020018681526020018581526020018460ff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff168152602001965050505050505060a06040518083038186803b158015613ba557600080fd5b505afa158015613bb9573d6000803e3d6000fd5b505050506040513d60a0811015613bcf57600080fd5b81019080805190602001909291908051906020019092919080519060200190929190805190602001909291908051906020019092919050505094509450945094509450613c2660648c61470a90919063ffffffff16565b831115613c9b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f544f4b454e20464545204558434545445320312500000000000000000000000081525060200191505060405180910390fd5b613caa8c868686868d87614b9d565b84341115613ccf57613cce33613cc98734614aeb90919063ffffffff16565b61524f565b5b613ce2838c614aeb90919063ffffffff16565b829650965050505050509550959350505050565b60008115613d7a57613d07876140b4565b613d79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4e4f54204445582050414952000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b60006040518060a001604052808973ffffffffffffffffffffffffffffffffffffffff1681526020018873ffffffffffffffffffffffffffffffffffffffff16815260200187815260200186815260200185815250905060066000815480929190600101919050559150806009600084815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550604082015181600201556060820151816003015560808201518160040155905050613ef882600a60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020614b6e90919063ffffffff16565b50613f263330888b73ffffffffffffffffffffffffffffffffffffffff16614a2a909392919063ffffffff16565b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff16837f601e52fd7ec7840490f1ae9c376bc3b32f6a6a6aac8dc10db76d87ef0fa45d328989604051808381526020018281526020019250505060405180910390a4509695505050505050565b600033905090565b6000613fc88273ffffffffffffffffffffffffffffffffffffffff16613aa7565b613fd55760009050614095565b8173ffffffffffffffffffffffffffffffffffffffff1663574f2ba36040518163ffffffff1660e01b815260040160206040518083038186803b15801561401b57600080fd5b505afa92505050801561404f57506040513d602081101561403b57600080fd5b810190808051906020019092919050505060015b61408f573d806000811461407f576040519150601f19603f3d011682016040523d82523d6000602084013e614084565b606091505b506000915050614095565b60019150505b919050565b60006140a98360000183615330565b60001c905092915050565b60006140d58273ffffffffffffffffffffffffffffffffffffffff16613aa7565b6140e257600090506143fe565b600082905060008173ffffffffffffffffffffffffffffffffffffffff1663c45a01556040518163ffffffff1660e01b815260040160206040518083038186803b15801561412f57600080fd5b505afa92505050801561416357506040513d602081101561414f57600080fd5b810190808051906020019092919050505060015b6141a5573d8060008114614193576040519150601f19603f3d011682016040523d82523d6000602084013e614198565b606091505b50600093505050506143fe565b80915050600760008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16614205576000925050506143fe565b60008173ffffffffffffffffffffffffffffffffffffffff1663e6a439058473ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b15801561426957600080fd5b505afa15801561427d573d6000803e3d6000fd5b505050506040513d602081101561429357600080fd5b81019080805190602001909291905050508573ffffffffffffffffffffffffffffffffffffffff1663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b1580156142ea57600080fd5b505afa1580156142fe573d6000803e3d6000fd5b505050506040513d602081101561431457600080fd5b81019080805190602001909291905050506040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b15801561438c57600080fd5b505afa1580156143a0573d6000803e3d6000fd5b505050506040513d60208110156143b657600080fd5b810190808051906020019092919050505090508473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161493505050505b919050565b6144a08363a9059cbb60e01b8484604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506153b3565b505050565b6000811480614573575060008373ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e30856040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b15801561453657600080fd5b505afa15801561454a573d6000803e3d6000fd5b505050506040513d602081101561456057600080fd5b8101908080519060200190929190505050145b6145c8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001806159a56036913960400191505060405180910390fd5b6146658363095ea7b360e01b8484604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506153b3565b505050565b600061467c836000018360001b6154a2565b905092915050565b6000808314156146975760009050614704565b60008284029050828482816146a857fe5b04146146ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602181526020018061595a6021913960400191505060405180910390fd5b809150505b92915050565b6000808211614781576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525060200191505060405180910390fd5b81838161478a57fe5b04905092915050565b600080600080600080600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ca1556c18b8b8b8b336040518663ffffffff1660e01b8152600401808673ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018481526020018360ff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019550505050505060806040518083038186803b15801561485e57600080fd5b505afa158015614872573d6000803e3d6000fd5b505050506040513d608081101561488857600080fd5b810190808051906020019092919080519060200190929190805190602001909291908051906020019092919050505093509350935093506148d360648a61470a90919063ffffffff16565b821115614948576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f544f4b454e20464545204558434545445320312500000000000000000000000081525060200191505060405180910390fd5b6149588a85858585600080614b9d565b8334111561497d5761497c336149778634614aeb90919063ffffffff16565b61524f565b5b614990828a614aeb90919063ffffffff16565b81955095505050505094509492505050565b600080828401905083811015614a20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b614ae5846323b872dd60e01b858585604051602401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506153b3565b50505050565b600082821115614b63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060200191505060405180910390fd5b818303905092915050565b6000614b80836000018360001b61558a565b905092915050565b6000614b96826000016155fa565b9050919050565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506000881115614d0f5787341015614c6a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f4554482046454553204e4f54204d45540000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614158015614ca75750600083115b15614d03576000614cd5612710614cc7868c61468490919063ffffffff16565b61470a90919063ffffffff16565b9050614ce1858261524f565b614cfd83614cf8838c614aeb90919063ffffffff16565b61524f565b50614d0e565b614d0d828961524f565b5b5b6000871115614ffe57600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415614dbb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f544f4b454e204645452054595045204e4f5420535550504f525445440000000081525060200191505060405180910390fd5b868173ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e33306040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b158015614e4157600080fd5b505afa158015614e55573d6000803e3d6000fd5b505050506040513d6020811015614e6b57600080fd5b81019080805190602001909291905050501015614ef0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f544f4b454e20464545204e4f54204d455400000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614158015614f2d5750600083115b15614fcf576000614f5b612710614f4d868b61468490919063ffffffff16565b61470a90919063ffffffff16565b9050614f8a3386838573ffffffffffffffffffffffffffffffffffffffff16614a2a909392919063ffffffff16565b614fc93384614fa2848c614aeb90919063ffffffff16565b8573ffffffffffffffffffffffffffffffffffffffff16614a2a909392919063ffffffff16565b50614ffd565b614ffc3383898473ffffffffffffffffffffffffffffffffffffffff16614a2a909392919063ffffffff16565b5b5b600086111561516a57858973ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e33306040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b15801561508d57600080fd5b505afa1580156150a1573d6000803e3d6000fd5b505050506040513d60208110156150b757600080fd5b8101908080519060200190929190505050101561513c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f4c5020544f4b454e20464545204e4f54204d455400000000000000000000000081525060200191505060405180910390fd5b6151693383888c73ffffffffffffffffffffffffffffffffffffffff16614a2a909392919063ffffffff16565b5b600085111561524457600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415615216576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f544f4b454e204645452054595045204e4f5420535550504f525445440000000081525060200191505060405180910390fd5b6152433330878473ffffffffffffffffffffffffffffffffffffffff16614a2a909392919063ffffffff16565b5b505050505050505050565b60008273ffffffffffffffffffffffffffffffffffffffff168260405180600001905060006040518083038185875af1925050503d80600081146152af576040519150601f19603f3d011682016040523d82523d6000602084013e6152b4565b606091505b505090508061532b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f424e42205452414e53464552204641494c45440000000000000000000000000081525060200191505060405180910390fd5b505050565b600081836000018054905011615391576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806158bb6022913960400191505060405180910390fd5b8260000182815481106153a057fe5b9060005260206000200154905092915050565b6000615415826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661560b9092919063ffffffff16565b905060008151111561549d5780806020019051602081101561543657600080fd5b810190808051906020019092919050505061549c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a81526020018061597b602a913960400191505060405180910390fd5b5b505050565b6000808360010160008481526020019081526020016000205490506000811461557e57600060018203905060006001866000018054905003905060008660000182815481106154ed57fe5b906000526020600020015490508087600001848154811061550a57fe5b906000526020600020018190555060018301876001016000838152602001908152602001600020819055508660000180548061554257fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050615584565b60009150505b92915050565b60006155968383615623565b6155ef5782600001829080600181540180825580915050600190039060005260206000200160009091909190915055826000018054905083600101600084815260200190815260200160002081905550600190506155f4565b600090505b92915050565b600081600001805490509050919050565b606061561a8484600085615646565b90509392505050565b600080836001016000848152602001908152602001600020541415905092915050565b6060824710156156a1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806159036026913960400191505060405180910390fd5b6156aa85613aa7565b61571c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b6020831061576b5780518252602082019150602081019050602083039250615748565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146157cd576040519150601f19603f3d011682016040523d82523d6000602084013e6157d2565b606091505b50915091506157e28282866157ee565b92505050949350505050565b606083156157fe578290506158b3565b6000835111156158115782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561587857808201518184015260208101905061585d565b50505050905090810190601f1680156158a55780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b939250505056fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e64734f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c494e56414c494420554e4c4f434b2054494d452c204d55535420424520554e49582054494d4520494e205345434f4e4453536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565645361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f20746f206e6f6e2d7a65726f20616c6c6f77616e6365a2646970667358221220791a9d2f847c1e920755b1ab60ee31cda91f9f0cba422017a344046443bbe62064736f6c63430007060033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000000000000000000000000000000000000000008000000000000000000000000085c76d5b4ce267afdfc24d6022262dcf9f0c4f4d000000000000000000000000e92651c0a980f60a7f352a4cbb06e8a429876d2400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000152ee697f2e276fa89e96742e9bb9ab1f2e61be3000000000000000000000000ef45d134b73241eda7703fa787148d9c9f4950b0000000000000000000000000d9473a05b2edf4f614593ba5d1dbd3021d8e0ebe0000000000000000000000007d82f56ea0820a9d42b01c3c28f1997721732218
-----Decoded View---------------
Arg [0] : supportedFactories (address[]): 0x152eE697f2E276fA89E96742e9bB9aB1F2E61bE3,0xEF45d134b73241eDa7703fa787148D9C9F4950b0,0xD9473A05b2edf4f614593bA5D1dBd3021d8e0Ebe,0x7d82F56ea0820A9d42b01C3C28F1997721732218
Arg [1] : _feesCalculator (address): 0x85c76D5B4CE267aFdFc24d6022262dCF9F0c4f4d
Arg [2] : _feesReceiver (address): 0xE92651C0A980f60A7F352a4CBB06E8a429876D24
Arg [3] : _feeToken (address): 0x0000000000000000000000000000000000000000
-----Encoded View---------------
9 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [1] : 00000000000000000000000085c76d5b4ce267afdfc24d6022262dcf9f0c4f4d
Arg [2] : 000000000000000000000000e92651c0a980f60a7f352a4cbb06e8a429876d24
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [5] : 000000000000000000000000152ee697f2e276fa89e96742e9bb9ab1f2e61be3
Arg [6] : 000000000000000000000000ef45d134b73241eda7703fa787148d9c9f4950b0
Arg [7] : 000000000000000000000000d9473a05b2edf4f614593ba5d1dbd3021d8e0ebe
Arg [8] : 0000000000000000000000007d82f56ea0820a9d42b01c3c28f1997721732218
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.