More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 413 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Set Tig Asset Va... | 189064157 | 703 days ago | IN | 0 ETH | 0.00012591 | ||||
| Set Tig Asset Va... | 187079151 | 709 days ago | IN | 0 ETH | 0.00027269 | ||||
| Whitelist Reward | 185797258 | 713 days ago | IN | 0 ETH | 0.00011069 | ||||
| Claim Tig | 185693784 | 713 days ago | IN | 0 ETH | 0.00012524 | ||||
| Claim Tig | 185693582 | 713 days ago | IN | 0 ETH | 0.00013162 | ||||
| Create Vest | 185693576 | 713 days ago | IN | 0 ETH | 0.00016214 | ||||
| Create Vest | 185693535 | 713 days ago | IN | 0 ETH | 0.0001574 | ||||
| Set Tig Asset Va... | 185676314 | 713 days ago | IN | 0 ETH | 0.00022208 | ||||
| Unwhitelist Rewa... | 185510151 | 714 days ago | IN | 0 ETH | 0.00010571 | ||||
| Whitelist Reward | 185504870 | 714 days ago | IN | 0 ETH | 0.00007531 | ||||
| Unwhitelist Rewa... | 185504756 | 714 days ago | IN | 0 ETH | 0.00006937 | ||||
| Whitelist Reward | 185504603 | 714 days ago | IN | 0 ETH | 0.00007413 | ||||
| Create Vest | 185503925 | 714 days ago | IN | 0 ETH | 0.00012692 | ||||
| Claim Tig | 185499407 | 714 days ago | IN | 0 ETH | 0.00006959 | ||||
| Create Vest | 185499314 | 714 days ago | IN | 0 ETH | 0.00009422 | ||||
| Create Vest | 185498560 | 714 days ago | IN | 0 ETH | 0.00009375 | ||||
| Create Vest | 185403391 | 714 days ago | IN | 0 ETH | 0.00014953 | ||||
| Create Vest | 185330741 | 714 days ago | IN | 0 ETH | 0.00010713 | ||||
| Claim Tig | 185175111 | 715 days ago | IN | 0 ETH | 0.00007539 | ||||
| Create Vest | 185174611 | 715 days ago | IN | 0 ETH | 0.00010342 | ||||
| Create Vest | 185064351 | 715 days ago | IN | 0 ETH | 0.00016183 | ||||
| Create Vest | 185047629 | 715 days ago | IN | 0 ETH | 0.00009831 | ||||
| Create Vest | 184771212 | 716 days ago | IN | 0 ETH | 0.00009988 | ||||
| Create Vest | 184421646 | 717 days ago | IN | 0 ETH | 0.00006564 | ||||
| Claim Tig | 184386862 | 717 days ago | IN | 0 ETH | 0.00007038 |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
xTIG
Compiler Version
v0.8.19+commit.7dd6d404
Optimization Enabled:
Yes with 1000000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
import "./utils/IterableMappingBool.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "./interfaces/IxTIG.sol";
import "./interfaces/IGovernanceStaking.sol";
import "./interfaces/IExtraRewards.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
contract xTIG is IxTIG, ERC20, Ownable {
using SafeERC20 for IERC20;
using IterableMappingBool for IterableMappingBool.Map;
// Constants
uint256 public constant DIVISION_CONSTANT = 1e10;
uint256 public constant EPOCH_PERIOD = 1 days;
uint256 public constant MAX_VESTING_PERIOD = 30 days;
uint256 public constant MAX_EARLY_UNLOCK_PENALTY = 75e8;
// Contracts and addresses
IERC20 public immutable tig;
IGovernanceStaking public immutable staking;
address public treasury;
address public trading;
IExtraRewards public extraRewards;
// xTIG settings
uint256 public vestingPeriod = 30 days;
uint256 public earlyUnlockPenalty = 5e9;
mapping(address => uint256) public tigAssetValue;
IterableMappingBool.Map private rewardTokens;
mapping(address => bool) public canAddFees;
// Reward distribution logic
mapping(uint256 => uint256) public epochFeesGenerated;
mapping(uint256 => uint256) public epochAllocation;
mapping(uint256 => uint256) public epochAllocationClaimed;
mapping(address => uint256) public accRewardsPerToken;
mapping(address => mapping(address => uint256)) public userPaid; // user => token => amount
mapping(uint256 => mapping(address => uint256)) public feesGenerated; // 7d epoch => trader => fees
mapping(address => RewardBatch[]) public userRewards;
// Helpers for UI
mapping(address => uint256) public lastClaimedEpoch; // Last xTIG claim / createVest
mapping(address => bool) public hasEarnedBefore; // Has earned xTIG before
/**
* @dev Throws if called by any account that is not permissioned to store fees generated by trading.
*/
modifier onlyPermissioned() {
require(canAddFees[msg.sender], "!Permission");
_;
}
/**
* @notice Constructor to initialize the contract
* @param name_ Token name
* @param symbol_ Token symbol
* @param _tig The TIG token address
* @param _staking The staking contract address
* @param _treasury The treasury address
*/
constructor(string memory name_, string memory symbol_, IERC20 _tig, IGovernanceStaking _staking, address _treasury) ERC20(name_, symbol_) {
require(
address(_tig) != address(0) &&
address(_staking) != address(0) &&
_treasury != address(0),
"Zero address"
);
tig = _tig;
staking = _staking;
treasury = _treasury;
tig.approve(address(_staking), type(uint256).max);
}
/**
* @notice Create vest xTIG from a specified block epoch to current epoch
* @param _from Epoch to start vesting xTIG from
*/
function createVest(uint256 _from) external {
uint256 _to = block.timestamp / EPOCH_PERIOD;
createVestTo(_from, _to);
}
/**
* @notice Create vest xTIG from a specified block epoch to another specified epoch
* @param _from Epoch to start vesting xTIG from
* @param _to Epoch to end at
*/
function createVestTo(uint256 _from, uint256 _to) public {
uint256 _totalAmount;
for (uint256 _epoch=_from; _epoch<_to; _epoch++) {
if (epochFeesGenerated[_epoch] == 0) {
continue;
}
uint256 _amount = epochAllocation[_epoch] * feesGenerated[_epoch][msg.sender] / epochFeesGenerated[_epoch];
if (_amount == 0) {
continue;
}
_totalAmount += _amount;
delete feesGenerated[_epoch][msg.sender];
epochAllocationClaimed[_epoch] += _amount;
}
require(_totalAmount != 0, "No fees generated by trader");
lastClaimedEpoch[msg.sender] = _to;
_claim(msg.sender);
userRewards[msg.sender].push(RewardBatch(_totalAmount, block.timestamp + vestingPeriod));
_mint(msg.sender, _totalAmount);
_updateUserPaid(msg.sender);
emit TigVested(msg.sender, _totalAmount);
if (vestingPeriod == 0) {
claimTig();
}
}
function claimTig() public {
uint256 _length = userRewards[msg.sender].length;
claimTigRanged(0, _length);
}
/**
* @dev Claims the TIG rewards for the caller.
* @notice This function allows the caller to claim their accumulated TIG rewards that have passed the vesting period.
* @param _from The index of the first reward to claim.
* @param _to The last index of the range of reward to claim, exclusive. This is to prevent gas limit from being exceeded.
*/
function claimTigRanged(uint256 _from, uint256 _to) public {
_claim(msg.sender);
RewardBatch[] storage rewardsStorage = userRewards[msg.sender];
uint256 _length = rewardsStorage.length;
require(_length >= _to, "_to exceeds len");
uint256 _amount;
while(_from < _to) {
RewardBatch memory reward = rewardsStorage[_from];
if (block.timestamp >= reward.unlockTime) {
_amount += reward.amount;
rewardsStorage[_from] = rewardsStorage[_length - 1];
rewardsStorage.pop();
_length--;
_to--;
} else {
_from++;
}
}
require(_amount != 0, "No TIG to claim");
_burn(msg.sender, _amount);
staking.unstake(_amount);
_updateUserPaid(msg.sender);
tig.safeTransfer(msg.sender, _amount);
emit TigClaimed(msg.sender, _amount);
}
function earlyClaimTig() external {
uint256 _length = userRewards[msg.sender].length;
earlyClaimTigRanged(0, _length);
}
/**
* @dev Claims the TIG rewards for the caller, with an early unlock penalty.
* @notice Claim accumulated TIG rewards, with a penalty applied to TIG that have not passed the vesting period.
* @param _from The index of the first reward to claim.
* @param _to The last index of the range of reward to claim, exclusive. This is to prevent gas limit from being exceeded.
*/
function earlyClaimTigRanged(uint256 _from, uint256 _to) public {
RewardBatch[] storage rewardsStorage = userRewards[msg.sender];
uint256 _length = rewardsStorage.length;
require(_length != 0, "No TIG to claim");
require(_length >= _to, "_to exceeds len");
_claim(msg.sender);
uint256 _unstakeAmount;
uint256 _userAmount;
while (_from < _to) {
RewardBatch memory reward = rewardsStorage[_from];
_unstakeAmount += reward.amount;
if (block.timestamp >= reward.unlockTime) {
_userAmount += reward.amount;
} else {
_userAmount += reward.amount*(DIVISION_CONSTANT-earlyUnlockPenalty)/DIVISION_CONSTANT;
}
rewardsStorage[_from] = rewardsStorage[_length - 1];
rewardsStorage.pop();
_length--;
_to--;
}
_burn(msg.sender, _unstakeAmount);
staking.unstake(_unstakeAmount);
uint256 _amountForTreasury = _unstakeAmount-_userAmount;
_updateUserPaid(msg.sender);
tig.safeTransfer(treasury, _amountForTreasury);
tig.safeTransfer(msg.sender, _userAmount);
emit EarlyTigClaimed(msg.sender, _userAmount, _amountForTreasury);
}
/**
* @dev Claims the fees generated by the caller.
* @notice This function allows the caller to claim the TIG staking rewards earned by holding xTIG.
*/
function claimFees() external {
_claim(msg.sender);
}
/**
* @dev Adds fees generated by a trader to the contract.
* @param _trader The address of the trader.
* @param _tigAsset The address of the asset in which fees were generated.
* @param _fees The amount of fees generated by the trader in the specified asset.
* @notice This function allows a permissioned address to add fees generated by a trader to the contract.
*/
function addFees(address _trader, address _tigAsset, uint256 _fees) external onlyPermissioned {
uint256 _value = _fees * tigAssetValue[_tigAsset] / 1e18;
uint256 _epoch = block.timestamp / EPOCH_PERIOD;
feesGenerated[_epoch][_trader] += _value;
if (!hasEarnedBefore[_trader]) {
hasEarnedBefore[_trader] = true;
lastClaimedEpoch[_trader] = _epoch;
}
epochFeesGenerated[_epoch] += _value;
emit FeesAdded(_trader, _tigAsset, _fees, _value);
}
/**
* @dev Adds TIG rewards to the contract for a specific epoch.
* @param _epoch The epoch for which to add the TIG rewards.
* @param _amount The amount of TIG rewards to add for the specified epoch.
* @notice This function allows the contract owner to add TIG rewards to the contract for a specific epoch.
*/
function addTigRewards(uint256 _epoch, uint256 _amount) external onlyOwner {
require(_epoch >= block.timestamp / EPOCH_PERIOD, "No past epochs");
tig.safeTransferFrom(msg.sender, address(this), _amount);
epochAllocation[_epoch] += _amount;
_distribute();
staking.stake(_amount, 0);
emit TigRewardsAdded(msg.sender, _amount);
}
/**
* @dev Sets the value of a tigAsset used in fee calculations.
* @param _tigAsset The address of the tigAsset.
* @param _value The value of the tigAsset.
* @notice This function allows the contract owner to set the value of a tigAsset used in fee calculations.
*/
function setTigAssetValue(address _tigAsset, uint256 _value) external onlyOwner {
tigAssetValue[_tigAsset] = _value;
emit TigAssetValueUpdated(_tigAsset, _value);
}
/**
* @dev Sets the permission for an address to add fees generated by traders.
* @param _address The address for which to set the fee permission.
* @param _allowed True to allow the address to add fees, false to disallow.
* @notice This function allows the contract owner to set the permission for an address to add fees generated by traders.
*/
function setCanAddFees(address _address, bool _allowed) external onlyOwner {
canAddFees[_address] = _allowed;
emit FeePermissionUpdated(_address, _allowed);
}
/**
* @dev Sets the treasury address for receiving assets.
* @param _address The address of the treasury.
* @notice This function allows the contract owner to set the treasury address for receiving assets.
*/
function setTreasury(address _address) external onlyOwner {
require(_address != address(0), "Zero address");
treasury = _address;
emit TreasuryUpdated(_address);
}
/**
* @dev Sets the contract address for optional extra rewards.
* @param _address The address of the contract implementing the IExtraRewards interface.
* @notice This function allows the contract owner to set the contract address for extra rewards.
*/
function setExtraRewards(address _address) external onlyOwner {
_distribute();
extraRewards = IExtraRewards(_address);
emit SetExtraRewards(_address);
}
/**
* @dev Sets the vesting period for xTIG tokens.
* @param _time The new vesting period in seconds.
* @notice This function allows the contract owner to set the vesting period for xTIG tokens.
*/
function setVestingPeriod(uint256 _time) external onlyOwner {
require(_time <= MAX_VESTING_PERIOD, "Period too long");
vestingPeriod = _time;
emit VestingPeriodUpdated(_time);
}
/**
* @dev Sets the early unlock penalty for xTIG tokens.
* @param _percent The new early unlock penalty as a percentage.
* @notice This function allows the contract owner to set the early unlock penalty for xTIG tokens.
*/
function setEarlyUnlockPenalty(uint256 _percent) external onlyOwner {
require(_percent <= MAX_EARLY_UNLOCK_PENALTY, "Bad percent");
earlyUnlockPenalty = _percent;
emit EarlyUnlockPenaltyUpdated(_percent);
}
/**
* @dev Whitelists a reward token for distribution.
* @param _rewardToken The address of the reward token to whitelist.
* @notice This function allows the contract owner to whitelist a reward token for distribution.
*/
function whitelistReward(address _rewardToken) external onlyOwner {
require(!rewardTokens.get(_rewardToken), "Already whitelisted");
rewardTokens.set(_rewardToken);
emit TokenWhitelisted(_rewardToken);
}
/**
* @dev Removes a reward token from the whitelist.
* @param _rewardToken The address of the reward token to remove from the whitelist.
* @notice This function allows the contract owner to remove a reward token from the whitelist.
*/
function unwhitelistReward(address _rewardToken) external onlyOwner {
require(rewardTokens.get(_rewardToken), "Not whitelisted");
rewardTokens.remove(_rewardToken);
emit TokenUnwhitelisted(_rewardToken);
}
/**
* @dev Returns the amount of TIG staking rewards this xTIG contract has earned.
* @param _token The address of the reward token for which to calculate pending rewards.
* @return The amount of reward tokens pending.
* @notice This function allows the caller to check the amount of TIG staking rewards this xTIG contract has earned.
*/
function contractPending(address _token) public view returns (uint256) {
return staking.pending(address(this), _token);
}
/**
* @dev Returns the amount of extra rewards this xTIG contract has earned.
* @param _token The address of the reward token for which to calculate pending rewards.
* @return The amount of reward tokens pending.
* @notice This function allows the caller to check the amount of extra rewards this xTIG contract has earned.
*/
function extraRewardsPending(address _token) public view returns (uint256) {
if (address(extraRewards) == address(0)) return 0;
return extraRewards.pending(address(this), _token);
}
/**
* @dev Returns the amount of rewards pending for the caller.
* @param _user The address of the user for which to calculate pending rewards.
* @param _token The address of the token for which to calculate pending rewards.
* @return The amount of rewards pending for the caller.
* @notice This function allows the caller to check the amount of an user's pending rewards.
*/
function pending(address _user, address _token) public view returns (uint256) {
if (stakedTigBalance() == 0 || totalSupply() == 0) return 0;
return balanceOf(_user) * (accRewardsPerToken[_token] + (contractPending(_token)*1e18/stakedTigBalance()) + (extraRewardsPending(_token)*1e18/totalSupply())) / 1e18 - userPaid[_user][_token];
}
/**
* @dev Returns the amount of TIG pending for the caller as a result of xTIG vesting.
* @param _user The address of the user for which to calculate pending TIG.
* @return The amount of TIG pending for the caller as a result of xTIG vesting.
* @notice This function allows the caller to check the amount of TIG pending for the caller as a result of xTIG vesting.
*/
function pendingTig(address _user) external view returns (uint256) {
RewardBatch[] memory rewards = userRewards[_user];
uint256 _length = rewards.length;
uint256 _amount;
for (uint256 i=0; i<_length; i++) {
RewardBatch memory reward = rewards[i];
if (block.timestamp >= reward.unlockTime) {
_amount = _amount + reward.amount;
}
}
return _amount;
}
/**
* @dev Returns the amount of TIG pending for the caller with an early unlock penalty.
* @param _user The address of the user for which to calculate pending rewards.
* @return The amount of TIG pending for the caller with an early unlock penalty.
* @notice This function allows the caller to check the amount of TIG pending for the caller with an early unlock penalty.
*/
function pendingEarlyTig(address _user) external view returns (uint256) {
RewardBatch[] memory rewards = userRewards[_user];
uint256 _length = rewards.length;
uint256 _amount;
for (uint256 i=0; i<_length; i++) {
RewardBatch memory reward = rewards[i];
if (block.timestamp >= reward.unlockTime) {
_amount += reward.amount;
} else {
_amount += reward.amount*(DIVISION_CONSTANT-earlyUnlockPenalty)/DIVISION_CONSTANT;
}
}
return _amount;
}
/**
* @dev Returns the amount of upcoming xTIG tokens that the caller will receive in the current epoch.
* @param _user The address of the user for which to calculate upcoming xTIG tokens.
* @return The amount of upcoming xTIG tokens that the caller will receive in the current epoch.
* @notice This function allows the caller to check the amount of upcoming xTIG tokens they will receive in the current epoch.
*/
function upcomingXTig(address _user) external view returns (uint256) {
uint256 _epoch = block.timestamp / EPOCH_PERIOD;
if (epochFeesGenerated[_epoch] == 0) return 0;
return epochAllocation[_epoch] * feesGenerated[_epoch][_user] / epochFeesGenerated[_epoch];
}
/**
* @dev Returns the amount of xTIG tokens claimable by the caller from a specified epoch to current epoch.
* @param _user The address of the user for which to calculate claimable xTIG tokens.
* @param _from The starting epoch for calculating claimable xTIG tokens.
* @return The amount of xTIG tokens claimable by the caller from a specified epoch to current epoch.
* @notice This function allows the caller to check the amount of xTIG tokens claimable from a specified epoch to current epoch.
*/
function claimableXTig(address _user, uint256 _from) external view returns (uint256) {
uint256 _to = block.timestamp / EPOCH_PERIOD;
return claimableXTigTo(_user, _from, _to);
}
/**
* @dev Returns the amount of xTIG tokens claimable by the caller in a specific epoch range.
* @param _user The address of the user for which to calculate claimable xTIG tokens.
* @param _from The starting epoch for calculating claimable xTIG tokens.
* @return The amount of xTIG tokens claimable by the caller in the specified epoch range.
* @notice This function allows the caller to check the amount of xTIG tokens claimable in a specific epoch range.
*/
function claimableXTigTo(address _user, uint256 _from, uint256 _to) public view returns (uint256) {
uint256 _amount;
for (uint256 _epoch=_from; _epoch<_to; _epoch++) {
if (epochFeesGenerated[_epoch] == 0) {
continue;
}
_amount += epochAllocation[_epoch] * feesGenerated[_epoch][_user] / epochFeesGenerated[_epoch];
}
return _amount;
}
/**
* @dev Returns the total amount of TIG tokens staked by the contract.
* @return The total amount of TIG tokens staked by the contract.
* @notice This function allows anyone to check the total amount of TIG tokens staked by the contract.
*/
function stakedTigBalance() public view returns (uint256) {
return staking.userStaked(address(this));
}
/**
* @dev Returns an array of vested xTIG batches for the given user.
* @param _user The address of the user for which to retrieve vested xTIG batches.
* @return An array of vested xTIG batches for the given user.
* @notice This function allows the caller to retrieve an array of vested xTIG batches for the given user.
*/
function userRewardBatches(address _user) external view returns (RewardBatch[] memory) {
return userRewards[_user];
}
/**
* @dev Returns the unclaimed allocation for a specific epoch.
* @param _epoch The epoch for which to retrieve the unclaimed allocation.
* @return The unclaimed allocation for the specified epoch.
* @notice This function allows the caller to retrieve the unclaimed allocation for a specific epoch.
*/
function unclaimedAllocation(uint256 _epoch) external view returns (uint256) {
return epochAllocation[_epoch] - epochAllocationClaimed[_epoch];
}
/**
* @dev Returns the current epoch.
* @return The current epoch.
* @notice This function allows anyone to check the current epoch.
*/
function currentEpoch() external view returns (uint256) {
return block.timestamp / EPOCH_PERIOD;
}
/**
* @dev Internal function to claim rewards for the caller.
* @param _user The address of the user for which to claim rewards.
* @notice This function allows the contract to internally claim rewards for the caller.
*/
function _claim(address _user) internal {
_distribute();
address[] memory _tokens = rewardTokens.keys;
uint256 _len = _tokens.length;
for (uint256 i=0; i<_len; i++) {
address _token = _tokens[i];
uint256 _pending = pending(_user, _token);
if (_pending != 0) {
userPaid[_user][_token] += _pending;
IERC20(_token).safeTransfer(_user, _pending);
emit RewardClaimed(_user, _pending);
}
}
}
/**
* @dev Internal function to distribute rewards among xTIG holders.
* @notice This function allows the contract to internally distribute rewards among xTIG holders.
*/
function _distribute() internal {
uint256 _length = rewardTokens.size();
uint256[] memory _balancesBefore = new uint256[](_length);
for (uint256 i=0; i<_length; i++) {
address _token = rewardTokens.getKeyAtIndex(i);
_balancesBefore[i] = IERC20(_token).balanceOf(address(this));
}
if (address(extraRewards) != address(0)) {
extraRewards.claim();
}
staking.claim();
for (uint256 i=0; i<_length; i++) {
address _token = rewardTokens.getKeyAtIndex(i);
uint256 _amount = IERC20(_token).balanceOf(address(this)) - _balancesBefore[i];
if (stakedTigBalance() == 0 || totalSupply() == 0) {
IERC20(_token).safeTransfer(treasury, _amount);
continue;
}
uint256 _amountPerStakedTig = _amount*1e18/stakedTigBalance();
accRewardsPerToken[_token] += _amountPerStakedTig;
IERC20(_token).safeTransfer(treasury, _amount-_amount*totalSupply()/stakedTigBalance());
}
}
/**
* @dev Internal function to update the paid rewards for a user.
* @param _user The address of the user for which to update the paid rewards.
* @notice This function allows the contract to internally update the paid rewards for a user.
*/
function _updateUserPaid(address _user) internal {
address[] memory _tokens = rewardTokens.keys;
uint256 _len = _tokens.length;
for (uint256 i=0; i<_len; i++) {
address _token = _tokens[i];
userPaid[_user][_token] = balanceOf(_user) * accRewardsPerToken[_token] / 1e18;
}
}
/**
* @dev Override transfer to disallow transfers.
*/
function _transfer(address, address, uint256) internal override {
revert("xTIG: No transfer");
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
pragma solidity ^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() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
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 {
_transferOwnership(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");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/ERC20.sol)
pragma solidity ^0.8.0;
import "./IERC20.sol";
import "./extensions/IERC20Metadata.sol";
import "../../utils/Context.sol";
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
* For a generic mechanism see {ERC20PresetMinterPauser}.
*
* TIP: For a detailed writeup see our guide
* https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* We have followed general OpenZeppelin Contracts guidelines: functions revert
* instead returning `false` on failure. This behavior is nonetheless
* conventional and does not conflict with the expectations of ERC20
* applications.
*
* Additionally, an {Approval} event is emitted on calls to {transferFrom}.
* This allows applications to reconstruct the allowance for all accounts just
* by listening to said events. Other implementations of the EIP may not emit
* these events, as it isn't required by the specification.
*
* Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
* functions have been added to mitigate the well-known issues around setting
* allowances. See {IERC20-approve}.
*/
contract ERC20 is Context, IERC20, IERC20Metadata {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
/**
* @dev Sets the values for {name} and {symbol}.
*
* The default value of {decimals} is 18. To select a different value for
* {decimals} you should overload it.
*
* All two of these values are immutable: they can only be set once during
* construction.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5.05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the value {ERC20} uses, unless this function is
* overridden;
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view virtual override returns (uint8) {
return 18;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/
function transfer(address to, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_transfer(owner, to, amount);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
* `transferFrom`. This is semantically equivalent to an infinite approval.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_approve(owner, spender, amount);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20}.
*
* NOTE: Does not update the allowance if the current allowance
* is the maximum `uint256`.
*
* Requirements:
*
* - `from` and `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
* - the caller must have allowance for ``from``'s tokens of at least
* `amount`.
*/
function transferFrom(
address from,
address to,
uint256 amount
) public virtual override returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, amount);
_transfer(from, to, amount);
return true;
}
/**
* @dev Atomically increases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, allowance(owner, spender) + addedValue);
return true;
}
/**
* @dev Atomically decreases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
address owner = _msgSender();
uint256 currentAllowance = allowance(owner, spender);
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(owner, spender, currentAllowance - subtractedValue);
}
return true;
}
/**
* @dev Moves `amount` of tokens from `from` to `to`.
*
* This internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
*/
function _transfer(
address from,
address to,
uint256 amount
) internal virtual {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(from, to, amount);
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
// Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by
// decrementing then incrementing.
_balances[to] += amount;
}
emit Transfer(from, to, amount);
_afterTokenTransfer(from, to, amount);
}
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply += amount;
unchecked {
// Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.
_balances[account] += amount;
}
emit Transfer(address(0), account, amount);
_afterTokenTransfer(address(0), account, amount);
}
/**
* @dev Destroys `amount` tokens from `account`, reducing the
* total supply.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
unchecked {
_balances[account] = accountBalance - amount;
// Overflow not possible: amount <= accountBalance <= totalSupply.
_totalSupply -= amount;
}
emit Transfer(account, address(0), amount);
_afterTokenTransfer(account, address(0), amount);
}
/**
* @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*/
function _approve(
address owner,
address spender,
uint256 amount
) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
/**
* @dev Updates `owner` s allowance for `spender` based on spent `amount`.
*
* Does not update the allowance amount in case of infinite allowance.
* Revert if not enough allowance is available.
*
* Might emit an {Approval} event.
*/
function _spendAllowance(
address owner,
address spender,
uint256 amount
) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
require(currentAllowance >= amount, "ERC20: insufficient allowance");
unchecked {
_approve(owner, spender, currentAllowance - amount);
}
}
}
/**
* @dev Hook that is called before any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
/**
* @dev Hook that is called after any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* has been transferred to `to`.
* - when `from` is zero, `amount` tokens have been minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens have been burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _afterTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*
* _Available since v4.1._
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the 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 `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, 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 `from` to `to` 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 from,
address to,
uint256 amount
) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/draft-IERC20Permit.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 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'
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) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
/**
* @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
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @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
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 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");
(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 functionCallWithValue(target, data, 0, "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");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, 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) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, 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) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// 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
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^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 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) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IExtraRewards {
function claim() external;
function pending(address _user, address _token) external view returns (uint256);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IGovernanceStaking {
function stake(uint256 _amount, uint256 _duration) external;
function unstake(uint256 _amount) external;
function claim() external;
function distribute(address _token, uint256 _amount) external;
function whitelistReward(address _rewardToken) external;
function pending(address _user, address _token) external view returns (uint256);
function userStaked(address _user) external view returns (uint256);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
interface IxTIG is IERC20 {
function vestingPeriod() external view returns (uint256);
function earlyUnlockPenalty() external view returns (uint256);
function epochFeesGenerated(uint256 _epoch) external view returns (uint256);
function epochAllocation(uint256 _epoch) external view returns (uint256);
function epochAllocationClaimed(uint256 _epoch) external view returns (uint256);
function feesGenerated(uint256 _epoch, address _trader) external view returns (uint256);
function tigAssetValue(address _tigAsset) external view returns (uint256);
function createVest(uint256 _from) external;
function claimTig() external;
function earlyClaimTig() external;
function claimFees() external;
function addFees(address _trader, address _tigAsset, uint256 _fees) external;
function addTigRewards(uint256 _epoch, uint256 _amount) external;
function setTigAssetValue(address _tigAsset, uint256 _value) external;
function setCanAddFees(address _address, bool _allowed) external;
function setExtraRewards(address _address) external;
function setVestingPeriod(uint256 _time) external;
function setEarlyUnlockPenalty(uint256 _percent) external;
function whitelistReward(address _rewardToken) external;
function contractPending(address _token) external view returns (uint256);
function extraRewardsPending(address _token) external view returns (uint256);
function pending(address _user, address _token) external view returns (uint256);
function pendingTig(address _user) external view returns (uint256);
function pendingEarlyTig(address _user) external view returns (uint256);
function upcomingXTig(address _user) external view returns (uint256);
function stakedTigBalance() external view returns (uint256);
function userRewardBatches(address _user) external view returns (RewardBatch[] memory);
function unclaimedAllocation(uint256 _epoch) external view returns (uint256);
function currentEpoch() external view returns (uint256);
struct RewardBatch {
uint256 amount;
uint256 unlockTime;
}
event TigRewardsAdded(address indexed sender, uint256 amount);
event TigVested(address indexed account, uint256 amount);
event TigClaimed(address indexed user, uint256 amount);
event EarlyTigClaimed(address indexed user, uint256 amount, uint256 penalty);
event TokenWhitelisted(address token);
event TokenUnwhitelisted(address token);
event RewardClaimed(address indexed user, uint256 reward);
event VestingPeriodUpdated(uint256 time);
event EarlyUnlockPenaltyUpdated(uint256 percent);
event FeePermissionUpdated(address indexed protocol, bool permission);
event TreasuryUpdated(address indexed treasury);
event SetExtraRewards(address indexed extraRewards);
event FeesAdded(address indexed _trader, address indexed _tigAsset, uint256 _amount, uint256 indexed _value);
event TigAssetValueUpdated(address indexed _tigAsset, uint256 indexed _value);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
library IterableMappingBool {
// Iterable mapping from address to bool;
struct Map {
address[] keys;
mapping(address => bool) values;
mapping(address => uint) indexOf;
}
function get(Map storage map, address key) internal view returns (bool) {
return map.values[key];
}
function getKeyAtIndex(Map storage map, uint index) internal view returns (address) {
return map.keys[index];
}
function size(Map storage map) internal view returns (uint) {
return map.keys.length;
}
function set(Map storage map, address key) internal {
if (!map.values[key]) {
map.values[key] = true;
map.indexOf[key] = map.keys.length;
map.keys.push(key);
}
}
function remove(Map storage map, address key) internal {
if (map.values[key]) {
delete map.values[key];
uint index = map.indexOf[key];
address lastKey = map.keys[map.keys.length - 1];
map.indexOf[lastKey] = index;
delete map.indexOf[key];
map.keys[index] = lastKey;
map.keys.pop();
}
}
}{
"optimizer": {
"enabled": true,
"runs": 1000000
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"metadata": {
"useLiteralContent": true
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"contract IERC20","name":"_tig","type":"address"},{"internalType":"contract IGovernanceStaking","name":"_staking","type":"address"},{"internalType":"address","name":"_treasury","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"penalty","type":"uint256"}],"name":"EarlyTigClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"percent","type":"uint256"}],"name":"EarlyUnlockPenaltyUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"protocol","type":"address"},{"indexed":false,"internalType":"bool","name":"permission","type":"bool"}],"name":"FeePermissionUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_trader","type":"address"},{"indexed":true,"internalType":"address","name":"_tigAsset","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"FeesAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"extraRewards","type":"address"}],"name":"SetExtraRewards","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_tigAsset","type":"address"},{"indexed":true,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"TigAssetValueUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TigClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TigRewardsAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TigVested","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"}],"name":"TokenUnwhitelisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"}],"name":"TokenWhitelisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"treasury","type":"address"}],"name":"TreasuryUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"VestingPeriodUpdated","type":"event"},{"inputs":[],"name":"DIVISION_CONSTANT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EPOCH_PERIOD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_EARLY_UNLOCK_PENALTY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_VESTING_PERIOD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"accRewardsPerToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_trader","type":"address"},{"internalType":"address","name":"_tigAsset","type":"address"},{"internalType":"uint256","name":"_fees","type":"uint256"}],"name":"addFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_epoch","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"addTigRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"canAddFees","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimTig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_from","type":"uint256"},{"internalType":"uint256","name":"_to","type":"uint256"}],"name":"claimTigRanged","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_from","type":"uint256"}],"name":"claimableXTig","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_from","type":"uint256"},{"internalType":"uint256","name":"_to","type":"uint256"}],"name":"claimableXTigTo","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"contractPending","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_from","type":"uint256"}],"name":"createVest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_from","type":"uint256"},{"internalType":"uint256","name":"_to","type":"uint256"}],"name":"createVestTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"earlyClaimTig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_from","type":"uint256"},{"internalType":"uint256","name":"_to","type":"uint256"}],"name":"earlyClaimTigRanged","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"earlyUnlockPenalty","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"epochAllocation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"epochAllocationClaimed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"epochFeesGenerated","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"extraRewards","outputs":[{"internalType":"contract IExtraRewards","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"extraRewardsPending","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"feesGenerated","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"hasEarnedBefore","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastClaimedEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"address","name":"_token","type":"address"}],"name":"pending","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"pendingEarlyTig","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"pendingTig","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"bool","name":"_allowed","type":"bool"}],"name":"setCanAddFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_percent","type":"uint256"}],"name":"setEarlyUnlockPenalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"setExtraRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tigAsset","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"setTigAssetValue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"setTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_time","type":"uint256"}],"name":"setVestingPeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakedTigBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"staking","outputs":[{"internalType":"contract IGovernanceStaking","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tig","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tigAssetValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"trading","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_epoch","type":"uint256"}],"name":"unclaimedAllocation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardToken","type":"address"}],"name":"unwhitelistReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"upcomingXTig","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"userPaid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"userRewardBatches","outputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"unlockTime","type":"uint256"}],"internalType":"struct IxTIG.RewardBatch[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"userRewards","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"unlockTime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vestingPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardToken","type":"address"}],"name":"whitelistReward","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60c060405262278d0060095564012a05f200600a553480156200002157600080fd5b5060405162004697380380620046978339810160408190526200004491620002d3565b848460036200005483826200040e565b5060046200006382826200040e565b505050620000806200007a6200019f60201b60201c565b620001a3565b6001600160a01b03831615801590620000a157506001600160a01b03821615155b8015620000b657506001600160a01b03811615155b620000f65760405162461bcd60e51b815260206004820152600c60248201526b5a65726f206164647265737360a01b604482015260640160405180910390fd5b6001600160a01b03838116608081905283821660a0819052600680546001600160a01b0319169385169390931790925560405163095ea7b360e01b8152600481019290925260001960248301529063095ea7b3906044016020604051808303816000875af11580156200016d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001939190620004da565b50505050505062000505565b3390565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200021d57600080fd5b81516001600160401b03808211156200023a576200023a620001f5565b604051601f8301601f19908116603f01168101908282118183101715620002655762000265620001f5565b816040528381526020925086838588010111156200028257600080fd5b600091505b83821015620002a6578582018301518183018401529082019062000287565b600093810190920192909252949350505050565b6001600160a01b0381168114620002d057600080fd5b50565b600080600080600060a08688031215620002ec57600080fd5b85516001600160401b03808211156200030457600080fd5b6200031289838a016200020b565b965060208801519150808211156200032957600080fd5b5062000338888289016200020b565b94505060408601516200034b81620002ba565b60608701519093506200035e81620002ba565b60808701519092506200037181620002ba565b809150509295509295909350565b600181811c908216806200039457607f821691505b602082108103620003b557634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200040957600081815260208120601f850160051c81016020861015620003e45750805b601f850160051c820191505b818110156200040557828155600101620003f0565b5050505b505050565b81516001600160401b038111156200042a576200042a620001f5565b62000442816200043b84546200037f565b84620003bb565b602080601f8311600181146200047a5760008415620004615750858301515b600019600386901b1c1916600185901b17855562000405565b600085815260208120601f198616915b82811015620004ab578886015182559484019460019091019084016200048a565b5085821015620004ca5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600060208284031215620004ed57600080fd5b81518015158114620004fe57600080fd5b9392505050565b60805160a05161412662000571600039600081816105be01528181610b790152818161165c015281816119aa01528181611b4e0152818161253e01526133a601526000818161080a015281816115d201528181611a5201528181611a9501526125d201526141266000f3fe608060405234801561001057600080fd5b50600436106103eb5760003560e01c80636b949d141161021a578063ab14154f11610135578063ddff6c0b116100c8578063ec44acf211610097578063f2fde38b1161007c578063f2fde38b14610991578063f41c33e9146109a4578063ff05db80146109c457600080fd5b8063ec44acf21461095e578063f0f442601461097e57600080fd5b8063ddff6c0b14610901578063e21c81d314610921578063e5a5e67414610941578063ea24ea3c1461094b57600080fd5b8063d642831f11610104578063d642831f14610882578063db89461b14610895578063dd62ed3e146108a8578063ddb52072146108ee57600080fd5b8063ab14154f1461083f578063bc2fde6014610847578063d294f0931461085a578063d3ff8e091461086257600080fd5b806395d89b41116101ad578063a457c2d71161017c578063a457c2d7146107e6578063a4813488146107f9578063a8780f5314610805578063a9059cbb1461082c57600080fd5b806395d89b41146107b95780639afe4d41146107c15780639c511ad4146107d4578063a2d6942e146107de57600080fd5b806376671808116101e9578063766718081461076d57806386e32fe9146107755780638da5cb5b14610788578063929b629c146107a657600080fd5b80636b949d141461071357806370a0823114610726578063715018a61461075c5780637313ee5a1461076457600080fd5b8063395093511161030a5780635d252bd61161029d57806362907ea31161026c57806362907ea3146106a457806363c2a20a146106ad57806365708083146106d55780636955fb36146106e857600080fd5b80635d252bd61461063e5780635eaca60414610651578063605544151461067157806361d027b31461068457600080fd5b80634cf088d9116102d95780634cf088d9146105b957806353e3f083146106055780635794f0d7146106185780635cf5272d1461062b57600080fd5b806339509351146105605780633dd7c05a1461057357806340bee0ed1461059357806344c95eb9146105a657600080fd5b806318160ddd1161038257806328d3eabe1161035157806328d3eabe14610512578063313ce567146105255780633299eac514610534578063388d89421461054057600080fd5b806318160ddd146104c157806319bc9ae8146104c957806323b872dd146104dc578063279efc63146104ef57600080fd5b8063095ea7b3116103be578063095ea7b314610460578063103d52251461048357806313814e2a1461048b57806317e72cdb1461049e57600080fd5b806304570ebd146103f057806305a251de1461041657806306fdde031461043657806308b4bd631461044b575b600080fd5b6104036103fe366004613c5c565b6109ef565b6040519081526020015b60405180910390f35b610403610424366004613c77565b60126020526000908152604090205481565b61043e610a7d565b60405161040d9190613cb4565b61045e610459366004613c77565b610b0f565b005b61047361046e366004613d05565b610b2e565b604051901515815260200161040d565b610403610b48565b61045e610499366004613d2f565b610bfe565b6104736104ac366004613c5c565b600f6020526000908152604090205460ff1681565b600254610403565b6104036104d7366004613d6b565b610e37565b6104736104ea366004613d2f565b610f6f565b6104736104fd366004613c5c565b60186020526000908152604090205460ff1681565b61045e610520366004613dac565b610f93565b6040516012815260200161040d565b6104036401bf08eb0081565b61040361054e366004613c5c565b60136020526000908152604090205481565b61047361056e366004613d05565b611026565b610586610581366004613c5c565b611072565b60405161040d9190613de3565b61045e6105a1366004613c77565b611108565b61045e6105b4366004613c5c565b6111b9565b6105e07f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161040d565b61045e610613366004613e32565b6112a1565b61045e610626366004613d05565b6114de565b61045e610639366004613e32565b61153a565b61045e61064c366004613e32565b6116ff565b61040361065f366004613c77565b60116020526000908152604090205481565b61040361067f366004613c5c565b611b00565b6006546105e09073ffffffffffffffffffffffffffffffffffffffff1681565b610403600a5481565b6106c06106bb366004613d05565b611bbc565b6040805192835260208301919091520161040d565b61045e6106e3366004613c77565b611bf8565b6104036106f6366004613e54565b601560209081526000928352604080842090915290825290205481565b61045e610721366004613c5c565b611ca4565b610403610734366004613c5c565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b61045e611d23565b61040360095481565b610403611d37565b610403610783366004613d05565b611d46565b60055473ffffffffffffffffffffffffffffffffffffffff166105e0565b6104036107b4366004613c5c565b611d6b565b61043e611df1565b6104036107cf366004613c5c565b611e00565b6104036201518081565b61045e611ef1565b6104736107f4366004613d05565b611f0f565b6104036402540be40081565b6105e07f000000000000000000000000000000000000000000000000000000000000000081565b61047361083a366004613d05565b611fe0565b61045e611fee565b610403610855366004613c5c565b612009565b61045e612131565b610403610870366004613c5c565b600b6020526000908152604090205481565b610403610890366004613e77565b61213a565b61045e6108a3366004613c5c565b6121d1565b6104036108b6366004613d6b565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6104036108fc366004613c77565b6122ba565b61040361090f366004613c77565b60106020526000908152604090205481565b6008546105e09073ffffffffffffffffffffffffffffffffffffffff1681565b61040362278d0081565b61045e610959366004613e32565b6122de565b6007546105e09073ffffffffffffffffffffffffffffffffffffffff1681565b61045e61098c366004613c5c565b612635565b61045e61099f366004613c5c565b612729565b6104036109b2366004613c5c565b60176020526000908152604090205481565b6104036109d2366004613d6b565b601460209081526000928352604080842090915290825290205481565b6000806109ff6201518042613ed9565b60008181526010602052604081205491925003610a1f5750600092915050565b6000818152601060209081526040808320546015835281842073ffffffffffffffffffffffffffffffffffffffff881685528352818420548585526011909352922054610a6c9190613f14565b610a769190613ed9565b9392505050565b606060038054610a8c90613f2b565b80601f0160208091040260200160405190810160405280929190818152602001828054610ab890613f2b565b8015610b055780601f10610ada57610100808354040283529160200191610b05565b820191906000526020600020905b815481529060010190602001808311610ae857829003601f168201915b5050505050905090565b6000610b1e6201518042613ed9565b9050610b2a82826112a1565b5050565b600033610b3c8185856127dd565b60019150505b92915050565b6040517facc3a9390000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063acc3a93990602401602060405180830381865afa158015610bd5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf99190613f7e565b905090565b336000908152600f602052604090205460ff16610c7c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f215065726d697373696f6e00000000000000000000000000000000000000000060448201526064015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82166000908152600b6020526040812054670de0b6b3a764000090610cb69084613f14565b610cc09190613ed9565b90506000610cd16201518042613ed9565b600081815260156020908152604080832073ffffffffffffffffffffffffffffffffffffffff8a168452909152812080549293508492909190610d15908490613f97565b909155505073ffffffffffffffffffffffffffffffffffffffff851660009081526018602052604090205460ff16610da35773ffffffffffffffffffffffffffffffffffffffff8516600090815260186020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055601790915290208190555b60008181526010602052604081208054849290610dc1908490613f97565b92505081905550818473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167f2bd3738c816b3b49aa6fdfd3d94fe964af5ad3398d3dfbf62c0251a772b62cf086604051610e2891815260200190565b60405180910390a45050505050565b6000610e41610b48565b1580610e4d5750600254155b15610e5a57506000610b42565b73ffffffffffffffffffffffffffffffffffffffff808416600090815260146020908152604080832093861683529290522054670de0b6b3a7640000610e9f60025490565b610ea885611d6b565b610eba90670de0b6b3a7640000613f14565b610ec49190613ed9565b610ecc610b48565b610ed586611b00565b610ee790670de0b6b3a7640000613f14565b610ef19190613ed9565b73ffffffffffffffffffffffffffffffffffffffff8616600090815260136020526040902054610f219190613f97565b610f2b9190613f97565b73ffffffffffffffffffffffffffffffffffffffff8616600090815260208190526040902054610f5b9190613f14565b610f659190613ed9565b610a769190613faa565b600033610f7d858285612990565b610f88858585612a67565b506001949350505050565b610f9b612ac9565b73ffffffffffffffffffffffffffffffffffffffff82166000818152600f602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915591519182527f4f47723fd7a04e5bd2c3ead0e8548b357d18e02b9c3ef9cfd741a2e29f1a409491015b60405180910390a25050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152812054909190610b3c908290869061106d908790613f97565b6127dd565b73ffffffffffffffffffffffffffffffffffffffff81166000908152601660209081526040808320805482518185028101850190935280835260609492939192909184015b828210156110fd578382906000526020600020906002020160405180604001604052908160008201548152602001600182015481525050815260200190600101906110b7565b505050509050919050565b611110612ac9565b62278d0081111561117d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f506572696f6420746f6f206c6f6e6700000000000000000000000000000000006044820152606401610c73565b60098190556040518181527fc21cb0f112058f1eb0e3313a577dfc27e6be5b39127591e05245343a422e4915906020015b60405180910390a150565b6111c1612ac9565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600d602052604090205460ff16611250576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f4e6f742077686974656c697374656400000000000000000000000000000000006044820152606401610c73565b61125b600c82612b4a565b60405173ffffffffffffffffffffffffffffffffffffffff821681527f108cc7e243d7eb6c2052789466e0961bb24cd62395e2c99e704001b48107a061906020016111ae565b6000825b828110156113725760008181526010602052604090205415611360576000818152601060209081526040808320546015835281842033855283528184205485855260119093529083205490916112fa91613f14565b6113049190613ed9565b9050806000036113145750611360565b61131e8184613f97565b600083815260156020908152604080832033845282528083208390558583526012909152812080549295508392909190611359908490613f97565b9091555050505b8061136a81613fbd565b9150506112a5565b50806000036113dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4e6f20666565732067656e6572617465642062792074726164657200000000006044820152606401610c73565b3360008181526017602052604090208390556113f890612d0f565b601660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060400160405280838152602001600954426114569190613f97565b90528154600181810184556000938452602093849020835160029093020191825592909101519101556114893382612e98565b61149233612f8b565b60405181815233907fd3a0ae61a716b832878d3efa7e651dda495884aa726d26e17e4754f17ae72a0e9060200160405180910390a26009546000036114d9576114d9611fee565b505050565b6114e6612ac9565b73ffffffffffffffffffffffffffffffffffffffff82166000818152600b6020526040808220849055518392917f3afbd4812bfd207933fdf7c147e3b75b1b74dda74766701c2a0ec79c9ada842591a35050565b611542612ac9565b61154f6201518042613ed9565b8210156115b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e6f20706173742065706f6368730000000000000000000000000000000000006044820152606401610c73565b6115fa73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163330846130f9565b60008281526011602052604081208054839290611618908490613f97565b9091555061162690506131d5565b6040517f7b0472f000000000000000000000000000000000000000000000000000000000815260048101829052600060248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690637b0472f090604401600060405180830381600087803b1580156116b557600080fd5b505af11580156116c9573d6000803e3d6000fd5b50506040518381523392507f870afb07fca67b69dd3985591162df5e817f6cab84fb60f2c7b49aa2823c7ed7915060200161101a565b3360009081526016602052604081208054909181900361177b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f4e6f2054494720746f20636c61696d00000000000000000000000000000000006044820152606401610c73565b828110156117e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f5f746f2065786365656473206c656e00000000000000000000000000000000006044820152606401610c73565b6117ee33612d0f565b6000805b8486101561197157600084878154811061180e5761180e613ff5565b906000526020600020906002020160405180604001604052908160008201548152602001600182015481525050905080600001518361184d9190613f97565b92508060200151421061186d5780516118669083613f97565b91506118a9565b6402540be400600a546402540be4006118869190613faa565b82516118929190613f14565b61189c9190613ed9565b6118a69083613f97565b91505b846118b5600186613faa565b815481106118c5576118c5613ff5565b90600052602060002090600202018588815481106118e5576118e5613ff5565b600091825260209091208254600290920201908155600191820154910155845485908061191457611914614024565b60008281526020812060027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909301928302018181556001015590558361195a81614053565b945050858061196890614053565b965050506117f2565b61197b338361361d565b6040517f2e17de78000000000000000000000000000000000000000000000000000000008152600481018390527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632e17de7890602401600060405180830381600087803b158015611a0357600080fd5b505af1158015611a17573d6000803e3d6000fd5b5050505060008183611a299190613faa565b9050611a3433612f8b565b600654611a7b9073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081169116836137e1565b611abc73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001633846137e1565b604080518381526020810183905233917fb034e6fe6c451f4adf82dae982ae1f3bf57fc9b0d525c5ce8076618c00ff46f2910160405180910390a250505050505050565b6040517f19bc9ae800000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff82811660248301526000917f0000000000000000000000000000000000000000000000000000000000000000909116906319bc9ae8906044015b602060405180830381865afa158015611b98573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b429190613f7e565b60166020528160005260406000208181548110611bd857600080fd5b600091825260209091206002909102018054600190910154909250905082565b611c00612ac9565b6401bf08eb00811115611c6f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f4261642070657263656e740000000000000000000000000000000000000000006044820152606401610c73565b600a8190556040518181527fdb5238db799e30b0f254a3356d2a39443e699256a8921c1a93005549af2a0388906020016111ae565b611cac612ac9565b611cb46131d5565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f89bfc9a76422bf48f177ce9437ea5353969bb785025ae24a085d02c5c5691d5790600090a250565b611d2b612ac9565b611d356000613837565b565b6000610bf96201518042613ed9565b600080611d566201518042613ed9565b9050611d6384848361213a565b949350505050565b60085460009073ffffffffffffffffffffffffffffffffffffffff16611d9357506000919050565b6008546040517f19bc9ae800000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8481166024830152909116906319bc9ae890604401611b7b565b606060048054610a8c90613f2b565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260166020908152604080832080548251818502810185019093528083528493849084015b82821015611e8657838290600052602060002090600202016040518060400160405290816000820154815260200160018201548152505081526020019060010190611e40565b50508251929350600091508190505b82811015611ee8576000848281518110611eb157611eb1613ff5565b6020026020010151905080602001514210611ed5578051611ed29084613f97565b92505b5080611ee081613fbd565b915050611e95565b50949350505050565b3360009081526016602052604081205490611f0c90826116ff565b50565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015611fd3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610c73565b610f8882868684036127dd565b600033610b3c818585612a67565b3360009081526016602052604081205490611f0c90826122de565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260166020908152604080832080548251818502810185019093528083528493849084015b8282101561208f57838290600052602060002090600202016040518060400160405290816000820154815260200160018201548152505081526020019060010190612049565b50508251929350600091508190505b82811015611ee85760008482815181106120ba576120ba613ff5565b60200260200101519050806020015142106120e25780516120db9084613f97565b925061211e565b6402540be400600a546402540be4006120fb9190613faa565b82516121079190613f14565b6121119190613ed9565b61211b9084613f97565b92505b508061212981613fbd565b91505061209e565b611d3533612d0f565b600080835b83811015611ee857600081815260106020526040902054156121bf576000818152601060209081526040808320546015835281842073ffffffffffffffffffffffffffffffffffffffff8b16855283528184205485855260119093529220546121a89190613f14565b6121b29190613ed9565b6121bc9083613f97565b91505b806121c981613fbd565b91505061213f565b6121d9612ac9565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600d602052604090205460ff1615612269576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f416c72656164792077686974656c6973746564000000000000000000000000006044820152606401610c73565b612274600c826138ae565b60405173ffffffffffffffffffffffffffffffffffffffff821681527f6a65f90b1a644d2faac467a21e07e50e3f8fa5846e26231d30ae79a417d3d262906020016111ae565b6000818152601260209081526040808320546011909252822054610b429190613faa565b6122e733612d0f565b336000908152601660205260409020805482811015612362576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f5f746f2065786365656473206c656e00000000000000000000000000000000006044820152606401610c73565b60005b8385101561249b57600083868154811061238157612381613ff5565b6000918252602091829020604080518082019091526002909202018054825260010154918101829052915042106124875780516123be9083613f97565b9150836123cc600185613faa565b815481106123dc576123dc613ff5565b90600052602060002090600202018487815481106123fc576123fc613ff5565b600091825260209091208254600290920201908155600191820154910155835484908061242b5761242b614024565b60008281526020812060027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909301928302018181556001015590558261247181614053565b935050848061247f90614053565b955050612495565b8561249181613fbd565b9650505b50612365565b80600003612505576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f4e6f2054494720746f20636c61696d00000000000000000000000000000000006044820152606401610c73565b61250f338261361d565b6040517f2e17de78000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632e17de7890602401600060405180830381600087803b15801561259757600080fd5b505af11580156125ab573d6000803e3d6000fd5b505050506125b833612f8b565b6125f973ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001633836137e1565b60405181815233907f0d19320b7f0d54529c06facb2cb3b5b50ca9b19af3642ca7dff95d3bca3784409060200160405180910390a25050505050565b61263d612ac9565b73ffffffffffffffffffffffffffffffffffffffff81166126ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f5a65726f206164647265737300000000000000000000000000000000000000006044820152606401610c73565b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b612731612ac9565b73ffffffffffffffffffffffffffffffffffffffff81166127d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610c73565b611f0c81613837565b73ffffffffffffffffffffffffffffffffffffffff831661287f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610c73565b73ffffffffffffffffffffffffffffffffffffffff8216612922576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610c73565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114612a615781811015612a54576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610c73565b612a6184848484036127dd565b50505050565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f785449473a204e6f207472616e736665720000000000000000000000000000006044820152606401610c73565b60055473ffffffffffffffffffffffffffffffffffffffff163314611d35576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c73565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604090205460ff1615610b2a5773ffffffffffffffffffffffffffffffffffffffff8116600090815260018084016020908152604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556002860190915282205484549092918591612be69190613faa565b81548110612bf657612bf6613ff5565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff908116808452600288019092526040808420869055908616835282209190915584549091508190859084908110612c5257612c52613ff5565b600091825260209091200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790558354849080612cb157612cb1614024565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550505050565b612d176131d5565b6000600c600001805480602002602001604051908101604052809291908181526020018280548015612d7f57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612d54575b505083519394506000925050505b81811015612a61576000838281518110612da957612da9613ff5565b602002602001015190506000612dbf8683610e37565b90508015612e835773ffffffffffffffffffffffffffffffffffffffff808716600090815260146020908152604080832093861683529290529081208054839290612e0b908490613f97565b90915550612e32905073ffffffffffffffffffffffffffffffffffffffff831687836137e1565b8573ffffffffffffffffffffffffffffffffffffffff167f106f923f993c2149d49b4255ff723acafa1f2d94393f561d3eda32ae348f724182604051612e7a91815260200190565b60405180910390a25b50508080612e9090613fbd565b915050612d8d565b73ffffffffffffffffffffffffffffffffffffffff8216612f15576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610c73565b8060026000828254612f279190613f97565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6000600c600001805480602002602001604051908101604052809291908181526020018280548015612ff357602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612fc8575b505083519394506000925050505b81811015612a6157600083828151811061301d5761301d613ff5565b60200260200101519050670de0b6b3a7640000601360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461309c8773ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6130a69190613f14565b6130b09190613ed9565b73ffffffffffffffffffffffffffffffffffffffff80871660009081526014602090815260408083209590931682529390935290912055806130f181613fbd565b915050613001565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052612a619085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152613976565b60006131e0600c5490565b905060008167ffffffffffffffff8111156131fd576131fd614088565b604051908082528060200260200182016040528015613226578160200160208202803683370190505b50905060005b82811015613302576000613241600c83613a82565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915073ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa1580156132ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132d29190613f7e565b8383815181106132e4576132e4613ff5565b602090810291909101015250806132fa81613fbd565b91505061322c565b5060085473ffffffffffffffffffffffffffffffffffffffff16156133a457600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634e71d92d6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561338b57600080fd5b505af115801561339f573d6000803e3d6000fd5b505050505b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16634e71d92d6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561340c57600080fd5b505af1158015613420573d6000803e3d6000fd5b5050505060005b828110156114d957600061343c600c83613a82565b9050600083838151811061345257613452613ff5565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa1580156134c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134eb9190613f7e565b6134f59190613faa565b90506134ff610b48565b158061350b5750600254155b1561353e576006546135379073ffffffffffffffffffffffffffffffffffffffff8481169116836137e1565b505061360b565b6000613548610b48565b61355a83670de0b6b3a7640000613f14565b6135649190613ed9565b73ffffffffffffffffffffffffffffffffffffffff841660009081526013602052604081208054929350839290919061359e908490613f97565b90915550506006546136079073ffffffffffffffffffffffffffffffffffffffff166135c8610b48565b6002546135d59086613f14565b6135df9190613ed9565b6135e99085613faa565b73ffffffffffffffffffffffffffffffffffffffff861691906137e1565b5050505b8061361581613fbd565b915050613427565b73ffffffffffffffffffffffffffffffffffffffff82166136c0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610c73565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015613776576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610c73565b73ffffffffffffffffffffffffffffffffffffffff83166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526114d99084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401613153565b6005805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604090205460ff16610b2a5773ffffffffffffffffffffffffffffffffffffffff16600081815260018381016020908152604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016841790558554600287018352908420819055918201855593825292902090910180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169091179055565b60006139d8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613ac29092919063ffffffff16565b8051909150156114d957808060200190518101906139f691906140b7565b6114d9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610c73565b6000826000018281548110613a9957613a99613ff5565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169392505050565b6060611d638484600085856000808673ffffffffffffffffffffffffffffffffffffffff168587604051613af691906140d4565b60006040518083038185875af1925050503d8060008114613b33576040519150601f19603f3d011682016040523d82523d6000602084013e613b38565b606091505b5091509150613b4987838387613b54565b979650505050505050565b60608315613bea578251600003613be35773ffffffffffffffffffffffffffffffffffffffff85163b613be3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610c73565b5081611d63565b611d638383815115613bff5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c739190613cb4565b803573ffffffffffffffffffffffffffffffffffffffff81168114613c5757600080fd5b919050565b600060208284031215613c6e57600080fd5b610a7682613c33565b600060208284031215613c8957600080fd5b5035919050565b60005b83811015613cab578181015183820152602001613c93565b50506000910152565b6020815260008251806020840152613cd3816040850160208701613c90565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60008060408385031215613d1857600080fd5b613d2183613c33565b946020939093013593505050565b600080600060608486031215613d4457600080fd5b613d4d84613c33565b9250613d5b60208501613c33565b9150604084013590509250925092565b60008060408385031215613d7e57600080fd5b613d8783613c33565b9150613d9560208401613c33565b90509250929050565b8015158114611f0c57600080fd5b60008060408385031215613dbf57600080fd5b613dc883613c33565b91506020830135613dd881613d9e565b809150509250929050565b602080825282518282018190526000919060409081850190868401855b82811015613e2557815180518552860151868501529284019290850190600101613e00565b5091979650505050505050565b60008060408385031215613e4557600080fd5b50508035926020909101359150565b60008060408385031215613e6757600080fd5b82359150613d9560208401613c33565b600080600060608486031215613e8c57600080fd5b613e9584613c33565b95602085013595506040909401359392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082613f0f577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b8082028115828204841417610b4257610b42613eaa565b600181811c90821680613f3f57607f821691505b602082108103613f78577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600060208284031215613f9057600080fd5b5051919050565b80820180821115610b4257610b42613eaa565b81810381811115610b4257610b42613eaa565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613fee57613fee613eaa565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008161406257614062613eaa565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156140c957600080fd5b8151610a7681613d9e565b600082516140e6818460208701613c90565b919091019291505056fea264697066735822122045ba299923e947bf714781cc8030041f68fc3727886e71a4a1c6b3c485e2d99464736f6c6343000813003300000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000003a33473d7990a605a88ac72a78ad4efc40a54adb0000000000000000000000006e8bfbb31a46d0f5502426050ea28b19f8e761f4000000000000000000000000f416c2b41fb6c592c9ba7cb6b2f985ed593a51d7000000000000000000000000000000000000000000000000000000000000000a566573746564205449470000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000047854494700000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106103eb5760003560e01c80636b949d141161021a578063ab14154f11610135578063ddff6c0b116100c8578063ec44acf211610097578063f2fde38b1161007c578063f2fde38b14610991578063f41c33e9146109a4578063ff05db80146109c457600080fd5b8063ec44acf21461095e578063f0f442601461097e57600080fd5b8063ddff6c0b14610901578063e21c81d314610921578063e5a5e67414610941578063ea24ea3c1461094b57600080fd5b8063d642831f11610104578063d642831f14610882578063db89461b14610895578063dd62ed3e146108a8578063ddb52072146108ee57600080fd5b8063ab14154f1461083f578063bc2fde6014610847578063d294f0931461085a578063d3ff8e091461086257600080fd5b806395d89b41116101ad578063a457c2d71161017c578063a457c2d7146107e6578063a4813488146107f9578063a8780f5314610805578063a9059cbb1461082c57600080fd5b806395d89b41146107b95780639afe4d41146107c15780639c511ad4146107d4578063a2d6942e146107de57600080fd5b806376671808116101e9578063766718081461076d57806386e32fe9146107755780638da5cb5b14610788578063929b629c146107a657600080fd5b80636b949d141461071357806370a0823114610726578063715018a61461075c5780637313ee5a1461076457600080fd5b8063395093511161030a5780635d252bd61161029d57806362907ea31161026c57806362907ea3146106a457806363c2a20a146106ad57806365708083146106d55780636955fb36146106e857600080fd5b80635d252bd61461063e5780635eaca60414610651578063605544151461067157806361d027b31461068457600080fd5b80634cf088d9116102d95780634cf088d9146105b957806353e3f083146106055780635794f0d7146106185780635cf5272d1461062b57600080fd5b806339509351146105605780633dd7c05a1461057357806340bee0ed1461059357806344c95eb9146105a657600080fd5b806318160ddd1161038257806328d3eabe1161035157806328d3eabe14610512578063313ce567146105255780633299eac514610534578063388d89421461054057600080fd5b806318160ddd146104c157806319bc9ae8146104c957806323b872dd146104dc578063279efc63146104ef57600080fd5b8063095ea7b3116103be578063095ea7b314610460578063103d52251461048357806313814e2a1461048b57806317e72cdb1461049e57600080fd5b806304570ebd146103f057806305a251de1461041657806306fdde031461043657806308b4bd631461044b575b600080fd5b6104036103fe366004613c5c565b6109ef565b6040519081526020015b60405180910390f35b610403610424366004613c77565b60126020526000908152604090205481565b61043e610a7d565b60405161040d9190613cb4565b61045e610459366004613c77565b610b0f565b005b61047361046e366004613d05565b610b2e565b604051901515815260200161040d565b610403610b48565b61045e610499366004613d2f565b610bfe565b6104736104ac366004613c5c565b600f6020526000908152604090205460ff1681565b600254610403565b6104036104d7366004613d6b565b610e37565b6104736104ea366004613d2f565b610f6f565b6104736104fd366004613c5c565b60186020526000908152604090205460ff1681565b61045e610520366004613dac565b610f93565b6040516012815260200161040d565b6104036401bf08eb0081565b61040361054e366004613c5c565b60136020526000908152604090205481565b61047361056e366004613d05565b611026565b610586610581366004613c5c565b611072565b60405161040d9190613de3565b61045e6105a1366004613c77565b611108565b61045e6105b4366004613c5c565b6111b9565b6105e07f0000000000000000000000006e8bfbb31a46d0f5502426050ea28b19f8e761f481565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161040d565b61045e610613366004613e32565b6112a1565b61045e610626366004613d05565b6114de565b61045e610639366004613e32565b61153a565b61045e61064c366004613e32565b6116ff565b61040361065f366004613c77565b60116020526000908152604090205481565b61040361067f366004613c5c565b611b00565b6006546105e09073ffffffffffffffffffffffffffffffffffffffff1681565b610403600a5481565b6106c06106bb366004613d05565b611bbc565b6040805192835260208301919091520161040d565b61045e6106e3366004613c77565b611bf8565b6104036106f6366004613e54565b601560209081526000928352604080842090915290825290205481565b61045e610721366004613c5c565b611ca4565b610403610734366004613c5c565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b61045e611d23565b61040360095481565b610403611d37565b610403610783366004613d05565b611d46565b60055473ffffffffffffffffffffffffffffffffffffffff166105e0565b6104036107b4366004613c5c565b611d6b565b61043e611df1565b6104036107cf366004613c5c565b611e00565b6104036201518081565b61045e611ef1565b6104736107f4366004613d05565b611f0f565b6104036402540be40081565b6105e07f0000000000000000000000003a33473d7990a605a88ac72a78ad4efc40a54adb81565b61047361083a366004613d05565b611fe0565b61045e611fee565b610403610855366004613c5c565b612009565b61045e612131565b610403610870366004613c5c565b600b6020526000908152604090205481565b610403610890366004613e77565b61213a565b61045e6108a3366004613c5c565b6121d1565b6104036108b6366004613d6b565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6104036108fc366004613c77565b6122ba565b61040361090f366004613c77565b60106020526000908152604090205481565b6008546105e09073ffffffffffffffffffffffffffffffffffffffff1681565b61040362278d0081565b61045e610959366004613e32565b6122de565b6007546105e09073ffffffffffffffffffffffffffffffffffffffff1681565b61045e61098c366004613c5c565b612635565b61045e61099f366004613c5c565b612729565b6104036109b2366004613c5c565b60176020526000908152604090205481565b6104036109d2366004613d6b565b601460209081526000928352604080842090915290825290205481565b6000806109ff6201518042613ed9565b60008181526010602052604081205491925003610a1f5750600092915050565b6000818152601060209081526040808320546015835281842073ffffffffffffffffffffffffffffffffffffffff881685528352818420548585526011909352922054610a6c9190613f14565b610a769190613ed9565b9392505050565b606060038054610a8c90613f2b565b80601f0160208091040260200160405190810160405280929190818152602001828054610ab890613f2b565b8015610b055780601f10610ada57610100808354040283529160200191610b05565b820191906000526020600020905b815481529060010190602001808311610ae857829003601f168201915b5050505050905090565b6000610b1e6201518042613ed9565b9050610b2a82826112a1565b5050565b600033610b3c8185856127dd565b60019150505b92915050565b6040517facc3a9390000000000000000000000000000000000000000000000000000000081523060048201526000907f0000000000000000000000006e8bfbb31a46d0f5502426050ea28b19f8e761f473ffffffffffffffffffffffffffffffffffffffff169063acc3a93990602401602060405180830381865afa158015610bd5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf99190613f7e565b905090565b336000908152600f602052604090205460ff16610c7c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f215065726d697373696f6e00000000000000000000000000000000000000000060448201526064015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82166000908152600b6020526040812054670de0b6b3a764000090610cb69084613f14565b610cc09190613ed9565b90506000610cd16201518042613ed9565b600081815260156020908152604080832073ffffffffffffffffffffffffffffffffffffffff8a168452909152812080549293508492909190610d15908490613f97565b909155505073ffffffffffffffffffffffffffffffffffffffff851660009081526018602052604090205460ff16610da35773ffffffffffffffffffffffffffffffffffffffff8516600090815260186020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055601790915290208190555b60008181526010602052604081208054849290610dc1908490613f97565b92505081905550818473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167f2bd3738c816b3b49aa6fdfd3d94fe964af5ad3398d3dfbf62c0251a772b62cf086604051610e2891815260200190565b60405180910390a45050505050565b6000610e41610b48565b1580610e4d5750600254155b15610e5a57506000610b42565b73ffffffffffffffffffffffffffffffffffffffff808416600090815260146020908152604080832093861683529290522054670de0b6b3a7640000610e9f60025490565b610ea885611d6b565b610eba90670de0b6b3a7640000613f14565b610ec49190613ed9565b610ecc610b48565b610ed586611b00565b610ee790670de0b6b3a7640000613f14565b610ef19190613ed9565b73ffffffffffffffffffffffffffffffffffffffff8616600090815260136020526040902054610f219190613f97565b610f2b9190613f97565b73ffffffffffffffffffffffffffffffffffffffff8616600090815260208190526040902054610f5b9190613f14565b610f659190613ed9565b610a769190613faa565b600033610f7d858285612990565b610f88858585612a67565b506001949350505050565b610f9b612ac9565b73ffffffffffffffffffffffffffffffffffffffff82166000818152600f602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915591519182527f4f47723fd7a04e5bd2c3ead0e8548b357d18e02b9c3ef9cfd741a2e29f1a409491015b60405180910390a25050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152812054909190610b3c908290869061106d908790613f97565b6127dd565b73ffffffffffffffffffffffffffffffffffffffff81166000908152601660209081526040808320805482518185028101850190935280835260609492939192909184015b828210156110fd578382906000526020600020906002020160405180604001604052908160008201548152602001600182015481525050815260200190600101906110b7565b505050509050919050565b611110612ac9565b62278d0081111561117d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f506572696f6420746f6f206c6f6e6700000000000000000000000000000000006044820152606401610c73565b60098190556040518181527fc21cb0f112058f1eb0e3313a577dfc27e6be5b39127591e05245343a422e4915906020015b60405180910390a150565b6111c1612ac9565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600d602052604090205460ff16611250576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f4e6f742077686974656c697374656400000000000000000000000000000000006044820152606401610c73565b61125b600c82612b4a565b60405173ffffffffffffffffffffffffffffffffffffffff821681527f108cc7e243d7eb6c2052789466e0961bb24cd62395e2c99e704001b48107a061906020016111ae565b6000825b828110156113725760008181526010602052604090205415611360576000818152601060209081526040808320546015835281842033855283528184205485855260119093529083205490916112fa91613f14565b6113049190613ed9565b9050806000036113145750611360565b61131e8184613f97565b600083815260156020908152604080832033845282528083208390558583526012909152812080549295508392909190611359908490613f97565b9091555050505b8061136a81613fbd565b9150506112a5565b50806000036113dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4e6f20666565732067656e6572617465642062792074726164657200000000006044820152606401610c73565b3360008181526017602052604090208390556113f890612d0f565b601660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060400160405280838152602001600954426114569190613f97565b90528154600181810184556000938452602093849020835160029093020191825592909101519101556114893382612e98565b61149233612f8b565b60405181815233907fd3a0ae61a716b832878d3efa7e651dda495884aa726d26e17e4754f17ae72a0e9060200160405180910390a26009546000036114d9576114d9611fee565b505050565b6114e6612ac9565b73ffffffffffffffffffffffffffffffffffffffff82166000818152600b6020526040808220849055518392917f3afbd4812bfd207933fdf7c147e3b75b1b74dda74766701c2a0ec79c9ada842591a35050565b611542612ac9565b61154f6201518042613ed9565b8210156115b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e6f20706173742065706f6368730000000000000000000000000000000000006044820152606401610c73565b6115fa73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000003a33473d7990a605a88ac72a78ad4efc40a54adb163330846130f9565b60008281526011602052604081208054839290611618908490613f97565b9091555061162690506131d5565b6040517f7b0472f000000000000000000000000000000000000000000000000000000000815260048101829052600060248201527f0000000000000000000000006e8bfbb31a46d0f5502426050ea28b19f8e761f473ffffffffffffffffffffffffffffffffffffffff1690637b0472f090604401600060405180830381600087803b1580156116b557600080fd5b505af11580156116c9573d6000803e3d6000fd5b50506040518381523392507f870afb07fca67b69dd3985591162df5e817f6cab84fb60f2c7b49aa2823c7ed7915060200161101a565b3360009081526016602052604081208054909181900361177b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f4e6f2054494720746f20636c61696d00000000000000000000000000000000006044820152606401610c73565b828110156117e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f5f746f2065786365656473206c656e00000000000000000000000000000000006044820152606401610c73565b6117ee33612d0f565b6000805b8486101561197157600084878154811061180e5761180e613ff5565b906000526020600020906002020160405180604001604052908160008201548152602001600182015481525050905080600001518361184d9190613f97565b92508060200151421061186d5780516118669083613f97565b91506118a9565b6402540be400600a546402540be4006118869190613faa565b82516118929190613f14565b61189c9190613ed9565b6118a69083613f97565b91505b846118b5600186613faa565b815481106118c5576118c5613ff5565b90600052602060002090600202018588815481106118e5576118e5613ff5565b600091825260209091208254600290920201908155600191820154910155845485908061191457611914614024565b60008281526020812060027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909301928302018181556001015590558361195a81614053565b945050858061196890614053565b965050506117f2565b61197b338361361d565b6040517f2e17de78000000000000000000000000000000000000000000000000000000008152600481018390527f0000000000000000000000006e8bfbb31a46d0f5502426050ea28b19f8e761f473ffffffffffffffffffffffffffffffffffffffff1690632e17de7890602401600060405180830381600087803b158015611a0357600080fd5b505af1158015611a17573d6000803e3d6000fd5b5050505060008183611a299190613faa565b9050611a3433612f8b565b600654611a7b9073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000003a33473d7990a605a88ac72a78ad4efc40a54adb81169116836137e1565b611abc73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000003a33473d7990a605a88ac72a78ad4efc40a54adb1633846137e1565b604080518381526020810183905233917fb034e6fe6c451f4adf82dae982ae1f3bf57fc9b0d525c5ce8076618c00ff46f2910160405180910390a250505050505050565b6040517f19bc9ae800000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff82811660248301526000917f0000000000000000000000006e8bfbb31a46d0f5502426050ea28b19f8e761f4909116906319bc9ae8906044015b602060405180830381865afa158015611b98573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b429190613f7e565b60166020528160005260406000208181548110611bd857600080fd5b600091825260209091206002909102018054600190910154909250905082565b611c00612ac9565b6401bf08eb00811115611c6f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f4261642070657263656e740000000000000000000000000000000000000000006044820152606401610c73565b600a8190556040518181527fdb5238db799e30b0f254a3356d2a39443e699256a8921c1a93005549af2a0388906020016111ae565b611cac612ac9565b611cb46131d5565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f89bfc9a76422bf48f177ce9437ea5353969bb785025ae24a085d02c5c5691d5790600090a250565b611d2b612ac9565b611d356000613837565b565b6000610bf96201518042613ed9565b600080611d566201518042613ed9565b9050611d6384848361213a565b949350505050565b60085460009073ffffffffffffffffffffffffffffffffffffffff16611d9357506000919050565b6008546040517f19bc9ae800000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8481166024830152909116906319bc9ae890604401611b7b565b606060048054610a8c90613f2b565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260166020908152604080832080548251818502810185019093528083528493849084015b82821015611e8657838290600052602060002090600202016040518060400160405290816000820154815260200160018201548152505081526020019060010190611e40565b50508251929350600091508190505b82811015611ee8576000848281518110611eb157611eb1613ff5565b6020026020010151905080602001514210611ed5578051611ed29084613f97565b92505b5080611ee081613fbd565b915050611e95565b50949350505050565b3360009081526016602052604081205490611f0c90826116ff565b50565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015611fd3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610c73565b610f8882868684036127dd565b600033610b3c818585612a67565b3360009081526016602052604081205490611f0c90826122de565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260166020908152604080832080548251818502810185019093528083528493849084015b8282101561208f57838290600052602060002090600202016040518060400160405290816000820154815260200160018201548152505081526020019060010190612049565b50508251929350600091508190505b82811015611ee85760008482815181106120ba576120ba613ff5565b60200260200101519050806020015142106120e25780516120db9084613f97565b925061211e565b6402540be400600a546402540be4006120fb9190613faa565b82516121079190613f14565b6121119190613ed9565b61211b9084613f97565b92505b508061212981613fbd565b91505061209e565b611d3533612d0f565b600080835b83811015611ee857600081815260106020526040902054156121bf576000818152601060209081526040808320546015835281842073ffffffffffffffffffffffffffffffffffffffff8b16855283528184205485855260119093529220546121a89190613f14565b6121b29190613ed9565b6121bc9083613f97565b91505b806121c981613fbd565b91505061213f565b6121d9612ac9565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600d602052604090205460ff1615612269576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f416c72656164792077686974656c6973746564000000000000000000000000006044820152606401610c73565b612274600c826138ae565b60405173ffffffffffffffffffffffffffffffffffffffff821681527f6a65f90b1a644d2faac467a21e07e50e3f8fa5846e26231d30ae79a417d3d262906020016111ae565b6000818152601260209081526040808320546011909252822054610b429190613faa565b6122e733612d0f565b336000908152601660205260409020805482811015612362576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f5f746f2065786365656473206c656e00000000000000000000000000000000006044820152606401610c73565b60005b8385101561249b57600083868154811061238157612381613ff5565b6000918252602091829020604080518082019091526002909202018054825260010154918101829052915042106124875780516123be9083613f97565b9150836123cc600185613faa565b815481106123dc576123dc613ff5565b90600052602060002090600202018487815481106123fc576123fc613ff5565b600091825260209091208254600290920201908155600191820154910155835484908061242b5761242b614024565b60008281526020812060027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909301928302018181556001015590558261247181614053565b935050848061247f90614053565b955050612495565b8561249181613fbd565b9650505b50612365565b80600003612505576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f4e6f2054494720746f20636c61696d00000000000000000000000000000000006044820152606401610c73565b61250f338261361d565b6040517f2e17de78000000000000000000000000000000000000000000000000000000008152600481018290527f0000000000000000000000006e8bfbb31a46d0f5502426050ea28b19f8e761f473ffffffffffffffffffffffffffffffffffffffff1690632e17de7890602401600060405180830381600087803b15801561259757600080fd5b505af11580156125ab573d6000803e3d6000fd5b505050506125b833612f8b565b6125f973ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000003a33473d7990a605a88ac72a78ad4efc40a54adb1633836137e1565b60405181815233907f0d19320b7f0d54529c06facb2cb3b5b50ca9b19af3642ca7dff95d3bca3784409060200160405180910390a25050505050565b61263d612ac9565b73ffffffffffffffffffffffffffffffffffffffff81166126ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f5a65726f206164647265737300000000000000000000000000000000000000006044820152606401610c73565b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b612731612ac9565b73ffffffffffffffffffffffffffffffffffffffff81166127d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610c73565b611f0c81613837565b73ffffffffffffffffffffffffffffffffffffffff831661287f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610c73565b73ffffffffffffffffffffffffffffffffffffffff8216612922576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610c73565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114612a615781811015612a54576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610c73565b612a6184848484036127dd565b50505050565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f785449473a204e6f207472616e736665720000000000000000000000000000006044820152606401610c73565b60055473ffffffffffffffffffffffffffffffffffffffff163314611d35576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c73565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604090205460ff1615610b2a5773ffffffffffffffffffffffffffffffffffffffff8116600090815260018084016020908152604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556002860190915282205484549092918591612be69190613faa565b81548110612bf657612bf6613ff5565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff908116808452600288019092526040808420869055908616835282209190915584549091508190859084908110612c5257612c52613ff5565b600091825260209091200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790558354849080612cb157612cb1614024565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550505050565b612d176131d5565b6000600c600001805480602002602001604051908101604052809291908181526020018280548015612d7f57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612d54575b505083519394506000925050505b81811015612a61576000838281518110612da957612da9613ff5565b602002602001015190506000612dbf8683610e37565b90508015612e835773ffffffffffffffffffffffffffffffffffffffff808716600090815260146020908152604080832093861683529290529081208054839290612e0b908490613f97565b90915550612e32905073ffffffffffffffffffffffffffffffffffffffff831687836137e1565b8573ffffffffffffffffffffffffffffffffffffffff167f106f923f993c2149d49b4255ff723acafa1f2d94393f561d3eda32ae348f724182604051612e7a91815260200190565b60405180910390a25b50508080612e9090613fbd565b915050612d8d565b73ffffffffffffffffffffffffffffffffffffffff8216612f15576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610c73565b8060026000828254612f279190613f97565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6000600c600001805480602002602001604051908101604052809291908181526020018280548015612ff357602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612fc8575b505083519394506000925050505b81811015612a6157600083828151811061301d5761301d613ff5565b60200260200101519050670de0b6b3a7640000601360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461309c8773ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6130a69190613f14565b6130b09190613ed9565b73ffffffffffffffffffffffffffffffffffffffff80871660009081526014602090815260408083209590931682529390935290912055806130f181613fbd565b915050613001565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052612a619085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152613976565b60006131e0600c5490565b905060008167ffffffffffffffff8111156131fd576131fd614088565b604051908082528060200260200182016040528015613226578160200160208202803683370190505b50905060005b82811015613302576000613241600c83613a82565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915073ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa1580156132ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132d29190613f7e565b8383815181106132e4576132e4613ff5565b602090810291909101015250806132fa81613fbd565b91505061322c565b5060085473ffffffffffffffffffffffffffffffffffffffff16156133a457600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634e71d92d6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561338b57600080fd5b505af115801561339f573d6000803e3d6000fd5b505050505b7f0000000000000000000000006e8bfbb31a46d0f5502426050ea28b19f8e761f473ffffffffffffffffffffffffffffffffffffffff16634e71d92d6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561340c57600080fd5b505af1158015613420573d6000803e3d6000fd5b5050505060005b828110156114d957600061343c600c83613a82565b9050600083838151811061345257613452613ff5565b60209081029190910101516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa1580156134c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134eb9190613f7e565b6134f59190613faa565b90506134ff610b48565b158061350b5750600254155b1561353e576006546135379073ffffffffffffffffffffffffffffffffffffffff8481169116836137e1565b505061360b565b6000613548610b48565b61355a83670de0b6b3a7640000613f14565b6135649190613ed9565b73ffffffffffffffffffffffffffffffffffffffff841660009081526013602052604081208054929350839290919061359e908490613f97565b90915550506006546136079073ffffffffffffffffffffffffffffffffffffffff166135c8610b48565b6002546135d59086613f14565b6135df9190613ed9565b6135e99085613faa565b73ffffffffffffffffffffffffffffffffffffffff861691906137e1565b5050505b8061361581613fbd565b915050613427565b73ffffffffffffffffffffffffffffffffffffffff82166136c0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610c73565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015613776576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610c73565b73ffffffffffffffffffffffffffffffffffffffff83166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526114d99084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401613153565b6005805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604090205460ff16610b2a5773ffffffffffffffffffffffffffffffffffffffff16600081815260018381016020908152604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016841790558554600287018352908420819055918201855593825292902090910180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169091179055565b60006139d8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613ac29092919063ffffffff16565b8051909150156114d957808060200190518101906139f691906140b7565b6114d9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610c73565b6000826000018281548110613a9957613a99613ff5565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169392505050565b6060611d638484600085856000808673ffffffffffffffffffffffffffffffffffffffff168587604051613af691906140d4565b60006040518083038185875af1925050503d8060008114613b33576040519150601f19603f3d011682016040523d82523d6000602084013e613b38565b606091505b5091509150613b4987838387613b54565b979650505050505050565b60608315613bea578251600003613be35773ffffffffffffffffffffffffffffffffffffffff85163b613be3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610c73565b5081611d63565b611d638383815115613bff5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c739190613cb4565b803573ffffffffffffffffffffffffffffffffffffffff81168114613c5757600080fd5b919050565b600060208284031215613c6e57600080fd5b610a7682613c33565b600060208284031215613c8957600080fd5b5035919050565b60005b83811015613cab578181015183820152602001613c93565b50506000910152565b6020815260008251806020840152613cd3816040850160208701613c90565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60008060408385031215613d1857600080fd5b613d2183613c33565b946020939093013593505050565b600080600060608486031215613d4457600080fd5b613d4d84613c33565b9250613d5b60208501613c33565b9150604084013590509250925092565b60008060408385031215613d7e57600080fd5b613d8783613c33565b9150613d9560208401613c33565b90509250929050565b8015158114611f0c57600080fd5b60008060408385031215613dbf57600080fd5b613dc883613c33565b91506020830135613dd881613d9e565b809150509250929050565b602080825282518282018190526000919060409081850190868401855b82811015613e2557815180518552860151868501529284019290850190600101613e00565b5091979650505050505050565b60008060408385031215613e4557600080fd5b50508035926020909101359150565b60008060408385031215613e6757600080fd5b82359150613d9560208401613c33565b600080600060608486031215613e8c57600080fd5b613e9584613c33565b95602085013595506040909401359392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082613f0f577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b8082028115828204841417610b4257610b42613eaa565b600181811c90821680613f3f57607f821691505b602082108103613f78577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600060208284031215613f9057600080fd5b5051919050565b80820180821115610b4257610b42613eaa565b81810381811115610b4257610b42613eaa565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613fee57613fee613eaa565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008161406257614062613eaa565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156140c957600080fd5b8151610a7681613d9e565b600082516140e6818460208701613c90565b919091019291505056fea264697066735822122045ba299923e947bf714781cc8030041f68fc3727886e71a4a1c6b3c485e2d99464736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000003a33473d7990a605a88ac72a78ad4efc40a54adb0000000000000000000000006e8bfbb31a46d0f5502426050ea28b19f8e761f4000000000000000000000000f416c2b41fb6c592c9ba7cb6b2f985ed593a51d7000000000000000000000000000000000000000000000000000000000000000a566573746564205449470000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000047854494700000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : name_ (string): Vested TIG
Arg [1] : symbol_ (string): xTIG
Arg [2] : _tig (address): 0x3A33473d7990a605a88ac72A78aD4EFC40a54ADB
Arg [3] : _staking (address): 0x6E8BFBb31A46D0F5502426050Ea28b19F8E761f4
Arg [4] : _treasury (address): 0xF416C2b41Fb6c592c9BA7cB6B2f985ed593A51d7
-----Encoded View---------------
9 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [2] : 0000000000000000000000003a33473d7990a605a88ac72a78ad4efc40a54adb
Arg [3] : 0000000000000000000000006e8bfbb31a46d0f5502426050ea28b19f8e761f4
Arg [4] : 000000000000000000000000f416c2b41fb6c592c9ba7cb6b2f985ed593a51d7
Arg [5] : 000000000000000000000000000000000000000000000000000000000000000a
Arg [6] : 5665737465642054494700000000000000000000000000000000000000000000
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [8] : 7854494700000000000000000000000000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.