Latest 25 from a total of 657 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Initiate Withdra... | 401370518 | 86 days ago | IN | 0 ETH | 0.00000074 | ||||
| Initiate Withdra... | 401369686 | 86 days ago | IN | 0 ETH | 0.00000069 | ||||
| Claim | 401369037 | 86 days ago | IN | 0 ETH | 0.00000031 | ||||
| Confirm Withdraw... | 375174237 | 162 days ago | IN | 0 ETH | 0.00000024 | ||||
| Claim | 375174077 | 162 days ago | IN | 0 ETH | 0.00000031 | ||||
| Claim | 366128703 | 188 days ago | IN | 0 ETH | 0.00000236 | ||||
| Confirm Withdraw... | 366128652 | 188 days ago | IN | 0 ETH | 0.00000479 | ||||
| Claim | 361027191 | 202 days ago | IN | 0 ETH | 0.00000032 | ||||
| Initiate Withdra... | 361026896 | 202 days ago | IN | 0 ETH | 0.00000073 | ||||
| Distribute | 361026691 | 202 days ago | IN | 0 ETH | 0.00000047 | ||||
| Claim | 361025868 | 202 days ago | IN | 0 ETH | 0.00000045 | ||||
| Set Autocompound... | 361025710 | 202 days ago | IN | 0 ETH | 0.0000015 | ||||
| Claim | 360981717 | 203 days ago | IN | 0 ETH | 0.00000084 | ||||
| Confirm Withdraw... | 360905314 | 203 days ago | IN | 0 ETH | 0.0000008 | ||||
| Claim | 311560243 | 346 days ago | IN | 0 ETH | 0.00000219 | ||||
| Claim | 302961751 | 371 days ago | IN | 0 ETH | 0.00000093 | ||||
| Claim | 296374284 | 390 days ago | IN | 0 ETH | 0.00000246 | ||||
| Claim | 296374236 | 390 days ago | IN | 0 ETH | 0.00000246 | ||||
| Claim | 292996047 | 400 days ago | IN | 0 ETH | 0.0000055 | ||||
| Confirm Withdraw... | 286906552 | 418 days ago | IN | 0 ETH | 0.00000113 | ||||
| Confirm Withdraw... | 286906525 | 418 days ago | IN | 0 ETH | 0.00000113 | ||||
| Initiate Withdra... | 281721108 | 433 days ago | IN | 0 ETH | 0.00000621 | ||||
| Initiate Withdra... | 281721075 | 433 days ago | IN | 0 ETH | 0.00000604 | ||||
| Confirm Withdraw... | 281721051 | 433 days ago | IN | 0 ETH | 0.00000504 | ||||
| Claim | 278538847 | 442 days ago | IN | 0 ETH | 0.00000362 |
Latest 2 internal transactions
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 168702149 | 764 days ago | Contract Creation | 0 ETH | |||
| 168702091 | 764 days ago | Contract Creation | 0 ETH |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
TigrisLPStaking
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 "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "./utils/IterableMappingBool.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
interface IAutoTigAsset is IERC20 {
function mint(address _to, uint256 _amount) external;
function burn(address _from, uint256 _amount) external;
}
contract TigrisLPStaking is Ownable {
using SafeERC20 for IERC20;
using IterableMappingBool for IterableMappingBool.Map;
IterableMappingBool.Map private assets;
uint256 public constant DIVISION_CONSTANT = 1e10;
uint256 public constant MAX_WITHDRAWAL_PERIOD = 30 days;
uint256 public constant MAX_DEPOSIT_FEE = 1e8; // 1%
uint256 public constant MAX_EARLY_WITHDRAW_FEE = 25e8; // 25%
uint256 public constant MAX_NORMAL_WITHDRAW_FEE = 50e8; // 50%
uint256 public constant MIN_INITIAL_DEPOSIT = 1e15;
address public treasury;
uint256 public withdrawalPeriod = 7 days;
uint256 public depositFee;
uint256 public earlyWithdrawFee = 10e8; // 10%
bool public earlyWithdrawalEnabled;
// Assets always have 18 decimals
mapping(address => uint256) public totalStaked; // [asset] => amount
mapping(address => uint256) public totalPendingWithdrawal; // [asset] => amount
mapping(address => mapping(address => bool)) public isUserAutocompounding; // [user][asset] => bool
mapping(address => mapping(address => uint256)) public userStaked; // [user][asset] => amount
mapping(address => mapping(address => uint256)) public userPendingWithdrawal; // [user][asset] => amount
mapping(address => mapping(address => uint256)) public withdrawTimestamp; // [user][asset] => timestamp
mapping(address => mapping(address => uint256)) public userPaid; // [user][asset] => amount
mapping(address => uint256) public accRewardsPerToken; // [asset] => amount
mapping(address => uint256) public compoundedAssetValue; // [asset] => amount
mapping(address => IAutoTigAsset) public autoTigAsset; // [asset] => autoTigAsset
mapping(address => uint256) public depositCap; // [asset] => amount
mapping(address => uint256) public normalWithdrawFee;
// Events
event Staked(address indexed asset, address indexed user, uint256 amount, uint256 fee);
event WithdrawalInitiated(address indexed asset, address indexed user, uint256 amount, uint256 timestamp);
event WithdrawalConfirmed(address indexed asset, address indexed user, uint256 amount, uint256 fee);
event WithdrawalCancelled(address indexed asset, address indexed user, uint256 amount);
event EarlyWithdrawal(address indexed asset, address indexed user, uint256 amount, uint256 fee);
event LPRewardClaimed(address indexed asset, address indexed user, uint256 amount);
event LPRewardDistributed(address indexed asset, uint256 amount);
event AssetWhitelisted(address indexed asset, IAutoTigAsset indexed autoTigAsset);
event AssetUnwhitelisted(address indexed asset);
event WithdrawalPeriodUpdated(uint256 newPeriod);
event TreasuryUpdated(address newTreasury);
event DepositFeeUpdated(uint256 newFee);
event EarlyWithdrawFeeUpdated(uint256 newFee);
event NormalWithdrawFeeUpdated(address asset, uint256 newFee);
event EarlyWithdrawalEnabled(bool enabled);
event UserAutocompoundingUpdated(address indexed user, address indexed asset, bool isAutocompounding);
event DepositCapUpdated(address indexed asset, uint256 newCap);
/**
* @dev Initializes the TigrisLPStaking contract with the provided treasury address.
* @param _treasury The address of the treasury where fees will be transferred.
* @notice The treasury address cannot be the zero address.
*/
constructor(address _treasury) {
require(_treasury != address(0), "ZeroAddress");
treasury = _treasury;
}
/**
* @dev Stakes a specified amount of tigAsset tokens.
* @param _tigAsset The address of the tigAsset token to stake.
* @param _amount The amount of tigAsset tokens to stake.
* @notice The `_amount` will be automatically adjusted to account for the deposit fee, if applicable.
* @notice If the user has opted for autocompounding, minted AutoTigAsset tokens will be received instead of staking.
* @notice Emits a `Staked` event on success.
*/
function stake(address _tigAsset, uint256 _amount) public {
require(_tigAsset != address(0), "ZeroAddress");
require(_amount != 0, "ZeroAmount");
require(assets.get(_tigAsset), "Asset not allowed");
uint256 _fee;
if (depositFee != 0) {
_fee = _amount * depositFee / DIVISION_CONSTANT;
_amount -= _fee;
}
require(totalDeposited(_tigAsset) + totalPendingWithdrawal[_tigAsset] + _amount <= depositCap[_tigAsset], "Deposit cap exceeded");
_claim(msg.sender, _tigAsset);
IERC20(_tigAsset).safeTransferFrom(msg.sender, address(this), _amount + _fee);
IERC20(_tigAsset).safeTransfer(treasury, _fee);
if (isUserAutocompounding[msg.sender][_tigAsset]) {
uint256 _autocompoundingAmount = _amount * 1e18 / compoundedAssetValue[_tigAsset];
autoTigAsset[_tigAsset].mint(msg.sender, _autocompoundingAmount);
} else {
totalStaked[_tigAsset] += _amount;
userStaked[msg.sender][_tigAsset] += _amount;
userPaid[msg.sender][_tigAsset] = userStaked[msg.sender][_tigAsset] * accRewardsPerToken[_tigAsset] / 1e18;
}
emit Staked(_tigAsset, msg.sender, _amount, _fee);
}
function initiateWithdrawalMax(address _tigAsset) external {
initiateWithdrawal(_tigAsset, userDeposited(msg.sender, _tigAsset));
}
/**
* @dev Initiates a withdrawal request for a specified amount of tigAsset tokens.
* @param _tigAsset The address of the tigAsset token for which the withdrawal is requested.
* @param _amount The amount of tigAsset tokens to withdraw.
* @notice Users can initiate withdrawal requests, and the funds will be available for withdrawal after the withdrawal period has elapsed.
* @notice If the user has opted for autocompounding, AutoTigAsset tokens will be burned instead of withdrawing LP tokens.
* @notice Emits a `WithdrawalInitiated` event on success.
*/
function initiateWithdrawal(address _tigAsset, uint256 _amount) public {
require(_tigAsset != address(0), "ZeroAddress");
require(_amount != 0, "Amount must be greater than 0");
require(userDeposited(msg.sender, _tigAsset) >= _amount, "Not enough staked");
_claim(msg.sender, _tigAsset);
if (isUserAutocompounding[msg.sender][_tigAsset]) {
uint256 _autocompoundingAmount = _amount * 1e18 / compoundedAssetValue[_tigAsset];
autoTigAsset[_tigAsset].burn(msg.sender, _autocompoundingAmount);
} else {
totalStaked[_tigAsset] -= _amount;
userStaked[msg.sender][_tigAsset] -= _amount;
userPaid[msg.sender][_tigAsset] = userStaked[msg.sender][_tigAsset] * accRewardsPerToken[_tigAsset] / 1e18;
}
userPendingWithdrawal[msg.sender][_tigAsset] += _amount;
totalPendingWithdrawal[_tigAsset] += _amount;
withdrawTimestamp[msg.sender][_tigAsset] = block.timestamp + withdrawalPeriod;
emit WithdrawalInitiated(_tigAsset, msg.sender, _amount, withdrawTimestamp[msg.sender][_tigAsset]);
// No need to wait for a 2-step withdrawal if the withdrawal period is 0
if (withdrawalPeriod == 0) {
confirmWithdrawal(_tigAsset);
}
}
/**
* @dev Confirms a withdrawal request for a specified amount of tigAssets.
* @param _tigAsset The address of the tigAsset for which the withdrawal is confirmed.
* @notice Users can confirm their withdrawal request after the withdrawal period has elapsed.
* @notice withdrawal incurs a withdraw fee, which is zero in normal circumstances defined by the `normalWithdrawFee` variable.
* @notice Emits a `WithdrawalConfirmed` event on success.
*/
function confirmWithdrawal(address _tigAsset) public {
require(_tigAsset != address(0), "ZeroAddress");
uint256 _pendingWithdrawal = userPendingWithdrawal[msg.sender][_tigAsset];
require(_pendingWithdrawal != 0, "Nothing to withdraw");
require(block.timestamp >= withdrawTimestamp[msg.sender][_tigAsset], "Withdrawal not ready");
delete userPendingWithdrawal[msg.sender][_tigAsset];
totalPendingWithdrawal[_tigAsset] -= _pendingWithdrawal;
uint256 _fee = _pendingWithdrawal * normalWithdrawFee[_tigAsset] / DIVISION_CONSTANT;
_pendingWithdrawal = _pendingWithdrawal - _fee;
IERC20(_tigAsset).safeTransfer(treasury, _fee);
IERC20(_tigAsset).safeTransfer(msg.sender, _pendingWithdrawal);
emit WithdrawalConfirmed(_tigAsset, msg.sender, _pendingWithdrawal, _fee);
}
/**
* @dev Cancels a withdrawal request for a specified amount of tigAssets.
* @param _tigAsset The address of the tigAsset for which the withdrawal is cancelled.
* @notice Users can cancel their withdrawal request before the withdrawal period has elapsed.
* @notice If the user has opted for autocompounding, the cancelled tigAssets will be converted back to AutoTigAsset tokens.
* @notice Emits a `WithdrawalCancelled` event on success.
*/
function cancelWithdrawal(address _tigAsset) external {
require(_tigAsset != address(0), "ZeroAddress");
uint256 _pendingWithdrawal = userPendingWithdrawal[msg.sender][_tigAsset];
require(_pendingWithdrawal != 0, "Nothing to cancel");
_claim(msg.sender, _tigAsset);
delete userPendingWithdrawal[msg.sender][_tigAsset];
totalPendingWithdrawal[_tigAsset] -= _pendingWithdrawal;
if (isUserAutocompounding[msg.sender][_tigAsset]) {
uint256 _autocompoundingAmount = _pendingWithdrawal * 1e18 / compoundedAssetValue[_tigAsset];
autoTigAsset[_tigAsset].mint(msg.sender, _autocompoundingAmount);
} else {
totalStaked[_tigAsset] += _pendingWithdrawal;
userStaked[msg.sender][_tigAsset] += _pendingWithdrawal;
userPaid[msg.sender][_tigAsset] = userStaked[msg.sender][_tigAsset] * accRewardsPerToken[_tigAsset] / 1e18;
}
emit WithdrawalCancelled(_tigAsset, msg.sender, _pendingWithdrawal);
}
function earlyWithdrawalMax(address _tigAsset) external {
earlyWithdrawal(_tigAsset, userDeposited(msg.sender, _tigAsset));
}
/**
* @dev Performs an early withdrawal of a specified amount of tigAssets.
* @param _tigAsset The address of the tigAsset for which the early withdrawal is performed.
* @param _amount The amount of tigAssets to withdraw.
* @notice Early withdrawal incurs a penalty fee, which is defined by the `earlyWithdrawFee` variable.
* @notice Users can perform early withdrawal if the `earlyWithdrawalEnabled` variable is set to true.
* @notice Emits an `EarlyWithdrawal` event on success.
*/
function earlyWithdrawal(address _tigAsset, uint256 _amount) public {
require(earlyWithdrawalEnabled, "Early withdrawal disabled");
require(_tigAsset != address(0), "ZeroAddress");
require(_amount != 0, "Amount must be greater than 0");
require(userDeposited(msg.sender, _tigAsset) >= _amount, "Not enough staked");
require(userPendingWithdrawal[msg.sender][_tigAsset] == 0, "Withdrawal already initiated");
_claim(msg.sender, _tigAsset);
if (isUserAutocompounding[msg.sender][_tigAsset]) {
uint256 _autocompoundingAmount = _amount * 1e18 / compoundedAssetValue[_tigAsset];
autoTigAsset[_tigAsset].burn(msg.sender, _autocompoundingAmount);
} else {
totalStaked[_tigAsset] -= _amount;
userStaked[msg.sender][_tigAsset] -= _amount;
userPaid[msg.sender][_tigAsset] = userStaked[msg.sender][_tigAsset] * accRewardsPerToken[_tigAsset] / 1e18;
}
uint256 _fee = _amount * (earlyWithdrawFee + normalWithdrawFee[_tigAsset]) / DIVISION_CONSTANT;
_amount = _amount - _fee;
IERC20(_tigAsset).safeTransfer(treasury, _fee);
IERC20(_tigAsset).safeTransfer(msg.sender, _amount);
emit EarlyWithdrawal(_tigAsset, msg.sender, _amount, _fee);
}
/**
* @dev Allows users to claim their accrued tigAsset rewards.
* @param _tigAsset The address of the tigAsset token for which the rewards are claimed.
* @notice The accrued rewards are calculated based on the user's share of staked tigAsset tokens and the distributed rewards.
* @notice Emits a `LPRewardClaimed` event on success.
*/
function claim(address _tigAsset) public {
_claim(msg.sender, _tigAsset);
}
function _claim(address _user, address _tigAsset) internal {
require(_tigAsset != address(0), "ZeroAddress");
uint256 _pending = pending(_user, _tigAsset);
if (_pending == 0) return;
userPaid[_user][_tigAsset] += _pending;
IERC20(_tigAsset).safeTransfer(_user, _pending);
emit LPRewardClaimed(_tigAsset, _user, _pending);
}
/**
* @dev Distributes rewards to stakers and autocompounders of a whitelisted tigAsset.
* @param _tigAsset The address of the tigAsset for which the rewards are being distributed.
* @param _amount The amount of tigAsset rewards to be distributed.
* @notice Only the contract owner can distribute rewards to stakers and autocompounders.
* @notice The rewards are distributed proportionally based on the total staked tigAssets and the total autocompounded tigAssets.
* @notice The distributed rewards are added to the reward pool and affect the reward accrual rate.
* @notice Emits an `LPRewardDistributed` event on success.
*/
function distribute(
address _tigAsset,
uint256 _amount
) external {
require(_tigAsset != address(0), "ZeroAddress");
if (!assets.get(_tigAsset) || totalDeposited(_tigAsset) == 0 || _amount == 0) return;
try IERC20(_tigAsset).transferFrom(msg.sender, address(this), _amount) {} catch {
return;
}
uint256 _toDistributeToStakers = _amount * totalStaked[_tigAsset] / totalDeposited(_tigAsset);
uint256 _toDistributeToAutocompounders = _amount - _toDistributeToStakers;
if (_toDistributeToStakers != 0) {
accRewardsPerToken[_tigAsset] += _toDistributeToStakers * 1e18 / totalStaked[_tigAsset];
}
if (_toDistributeToAutocompounders != 0) {
compoundedAssetValue[_tigAsset] += _toDistributeToAutocompounders * 1e18 / totalAutocompounding(_tigAsset);
}
emit LPRewardDistributed(_tigAsset, _amount);
}
/**
* @dev Sets the autocompounding option for a tigAsset.
* @param _tigAsset The address of the tigAsset for which the autocompounding option is being set.
* @param _isAutocompounding A boolean indicating whether autocompounding is enabled or disabled for the user.
* @notice Users can enable or disable autocompounding for their staked tigAssets.
* @notice If autocompounding is enabled, tigAssets will be converted to AutoTigAsset tokens.
* @notice If autocompounding is disabled, AutoTigAsset tokens will be converted back to tigAssets.
* @notice Emits a `UserAutocompoundingUpdated` event on success.
*/
function setAutocompounding(address _tigAsset, bool _isAutocompounding) public {
require(_tigAsset != address(0), "ZeroAddress");
_claim(msg.sender, _tigAsset);
isUserAutocompounding[msg.sender][_tigAsset] = _isAutocompounding;
if (_isAutocompounding) {
uint256 _toCompoundedAssets = userStaked[msg.sender][_tigAsset] * 1e18 / compoundedAssetValue[_tigAsset];
totalStaked[_tigAsset] -= userStaked[msg.sender][_tigAsset];
delete userStaked[msg.sender][_tigAsset];
autoTigAsset[_tigAsset].mint(msg.sender, _toCompoundedAssets);
} else {
uint256 _autoTigAssetBalance = userAutocompounding(msg.sender, _tigAsset);
uint256 _toStakedAssets = _autoTigAssetBalance * compoundedAssetValue[_tigAsset] / 1e18;
autoTigAsset[_tigAsset].burn(msg.sender, _autoTigAssetBalance);
userPaid[msg.sender][_tigAsset] += _toStakedAssets * accRewardsPerToken[_tigAsset] / 1e18;
totalStaked[_tigAsset] += _toStakedAssets;
userStaked[msg.sender][_tigAsset] += _toStakedAssets;
}
emit UserAutocompoundingUpdated(msg.sender, _tigAsset, _isAutocompounding);
}
/**
* @dev Whitelists an tigAsset for staking.
* @param _tigAsset The address of the tigAsset to be whitelisted.
* @param _initialDeposit The initial amount of tigAsset to be deposited after whitelisting.
* @notice Only the contract owner can whitelist tigAssets.
* @notice Emits an `AssetWhitelisted` event on success.
*/
function whitelistAsset(address _tigAsset, uint256 _initialDeposit) external onlyOwner {
require(_tigAsset != address(0), "ZeroAddress");
require(!assets.get(_tigAsset), "Already whitelisted");
assets.set(_tigAsset);
IAutoTigAsset _autoTigAsset = autoTigAsset[_tigAsset];
if (address(_autoTigAsset) == address(0)) {
require(_initialDeposit >= MIN_INITIAL_DEPOSIT, "Initial deposit too small");
_autoTigAsset = new AutoTigAsset(_tigAsset);
autoTigAsset[_tigAsset] = _autoTigAsset;
compoundedAssetValue[_tigAsset] = 1e18;
// Prevent small malicious first deposit
setAutocompounding(_tigAsset, true);
stake(_tigAsset, _initialDeposit);
}
emit AssetWhitelisted(_tigAsset, _autoTigAsset);
}
/**
* @dev Removes an tigAsset from the whitelist.
* @param _tigAsset The address of the tigAsset to be removed from the whitelist.
* @notice Only the contract owner can remove tigAsset from the whitelist.
* @notice Emits an `AssetUnwhitelisted` event on success.
*/
function unwhitelistAsset(address _tigAsset) external onlyOwner {
require(_tigAsset != address(0), "ZeroAddress");
require(assets.get(_tigAsset), "Not whitelisted");
assets.remove(_tigAsset);
emit AssetUnwhitelisted(_tigAsset);
}
/**
* @dev Updates the withdrawal period.
* @param _withdrawalPeriod The new withdrawal period, specified in seconds.
* @notice Only the contract owner can update the withdrawal period.
* @notice The maximum allowed withdrawal period is `MAX_WITHDRAWAL_PERIOD`.
* @notice Emits a `WithdrawalPeriodUpdated` event on success.
*/
function setWithdrawalPeriod(uint256 _withdrawalPeriod) external onlyOwner {
require(_withdrawalPeriod <= MAX_WITHDRAWAL_PERIOD, "Withdrawal period too long");
withdrawalPeriod = _withdrawalPeriod;
emit WithdrawalPeriodUpdated(_withdrawalPeriod);
}
/**
* @dev Updates the treasury address to receive fees.
* @param _treasury The address of the new treasury contract.
* @notice Only the contract owner can update the treasury address.
* @notice Emits a `TreasuryUpdated` event on success.
*/
function setTreasury(address _treasury) external onlyOwner {
require(_treasury != address(0), "ZeroAddress");
treasury = _treasury;
emit TreasuryUpdated(_treasury);
}
/**
* @dev Updates the deposit fee for tigAssets.
* @param _depositFee The new deposit fee, expressed as a percentage with `DIVISION_CONSTANT` divisor.
* @notice Only the contract owner can update the deposit fee.
* @notice The maximum allowed deposit fee is `MAX_DEPOSIT_FEE`.
* @notice Emits a `DepositFeeUpdated` event on success.
*/
function setDepositFee(uint256 _depositFee) external onlyOwner {
require(_depositFee <= MAX_DEPOSIT_FEE, "Fee too high");
depositFee = _depositFee;
emit DepositFeeUpdated(_depositFee);
}
/**
* @dev Updates the early withdrawal fee for tigAssets.
* @param _earlyWithdrawFee The new early withdrawal fee, expressed as a percentage with `DIVISION_CONSTANT` divisor.
* @notice Only the contract owner can update the early withdrawal fee.
* @notice The maximum allowed early withdrawal fee is `MAX_EARLY_WITHDRAW_FEE`.
* @notice Emits an `EarlyWithdrawFeeUpdated` event on success.
*/
function setEarlyWithdrawFee(uint256 _earlyWithdrawFee) external onlyOwner {
require(_earlyWithdrawFee <= MAX_EARLY_WITHDRAW_FEE, "Fee too high");
earlyWithdrawFee = _earlyWithdrawFee;
emit EarlyWithdrawFeeUpdated(_earlyWithdrawFee);
}
/**
* @dev Updates the normal withdrawal fee for tigAssets.
* @param _asset The address of the asset for which the normal withdrawal fee is being updated.
* @param _normalWithdrawFee The new normal withdrawal fee, expressed as a percentage with `DIVISION_CONSTANT` divisor.
* @notice Only the contract owner can update the normal withdrawal fee.
* @notice The maximum allowed normal withdrawal fee is `MAX_NORMAL_WITHDRAW_FEE`.
* @notice Emits an `NormalWithdrawFeeUpdated` event on success.
*/
function setNormalWithdrawFee(address _asset, uint256 _normalWithdrawFee) external onlyOwner {
require(_normalWithdrawFee <= MAX_NORMAL_WITHDRAW_FEE, "Fee too high");
normalWithdrawFee[_asset] = _normalWithdrawFee;
emit NormalWithdrawFeeUpdated(_asset, _normalWithdrawFee);
}
/**
* @dev Enables or disables early withdrawal for tigAssets.
* @param _enabled A boolean indicating whether early withdrawal is enabled or disabled.
* @notice Only the contract owner can enable or disable early withdrawal.
* @notice Emits an `EarlyWithdrawalEnabled` event on success.
*/
function setEarlyWithdrawalEnabled(bool _enabled) external onlyOwner {
earlyWithdrawalEnabled = _enabled;
emit EarlyWithdrawalEnabled(_enabled);
}
/**
* @dev Updates the deposit cap for a tigAsset.
* @param _tigAsset The address of the tigAsset for which the deposit cap is being updated.
* @param _depositCap The new deposit cap for the tigAsset.
* @notice Only the contract owner can update the deposit cap for tigAssets.
* @notice Emits a `DepositCapUpdated` event on success.
*/
function setDepositCap(address _tigAsset, uint256 _depositCap) external onlyOwner {
require(_tigAsset != address(0), "ZeroAddress");
depositCap[_tigAsset] = _depositCap;
emit DepositCapUpdated(_tigAsset, _depositCap);
}
/**
* @dev Returns the total amount of tigAssets deposited and autocompounded for a specific tigAsset.
* @param _tigAsset The address of the tigAsset for which the total deposited amount is requested.
* @return The total amount of tigAssets deposited and autocompounded for the given tigAsset.
*/
function totalDeposited(address _tigAsset) public view returns (uint256) {
return totalAutocompounding(_tigAsset) * compoundedAssetValue[_tigAsset] / 1e18 + totalStaked[_tigAsset];
}
/**
* @dev Returns the pending rewards of a user for a specific tigAsset.
* @param _user The address of the user for whom the pending rewards are requested.
* @param _tigAsset The address of the tigAsset for which the pending rewards are requested.
* @return The amount of pending rewards for the user in the given tigAsset.
* @notice If the user has autocompounding enabled for the tigAsset, the function returns 0, as autocompounders do not earn rewards as pending rewards.
*/
function pending(address _user, address _tigAsset) public view returns (uint256) {
if (isUserAutocompounding[_user][_tigAsset]) {
return 0;
}
return userStaked[_user][_tigAsset] * accRewardsPerToken[_tigAsset] / 1e18 - userPaid[_user][_tigAsset];
}
/**
* @dev Returns the total amount of tigAssets deposited by a user for a specific tigAsset.
* @param _user The address of the user for whom the deposited amount is requested.
* @param _tigAsset The address of the tigAsset for which the deposited amount is requested.
* @return The total amount of tigAssets deposited by the user in the given tigAsset.
* @notice If the user has autocompounding enabled for the tigAsset, the function returns the equivalent amount of tigAssets based on the compoundedAssetValue.
* @notice If the user does not have autocompounding enabled, the function returns the amount of tigAssets staked directly.
*/
function userDeposited(address _user, address _tigAsset) public view returns (uint256) {
if (isUserAutocompounding[_user][_tigAsset]) {
return userAutocompounding(_user, _tigAsset) * compoundedAssetValue[_tigAsset] / 1e18;
} else {
return userStaked[_user][_tigAsset];
}
}
/**
* @dev Returns the total amount of AutoTigAsset tokens (autocompounded tigAssets) for a specific tigAsset.
* @param _tigAsset The address of the tigAsset for which the total autocompounded amount is requested.
* @return The total amount of AutoTigAsset tokens (autocompounded tigAssets) for the given tigAsset.
*/
function totalAutocompounding(address _tigAsset) public view returns (uint256) {
return IERC20(autoTigAsset[_tigAsset]).totalSupply();
}
/**
* @dev Returns the amount of AutoTigAsset tokens (autocompounded tigAssets) held by a user for a specific tigAsset.
* @param _user The address of the user for whom the amount of AutoTigAsset tokens is requested.
* @param _tigAsset The address of the tigAsset for which the amount of AutoTigAsset tokens is requested.
* @return The amount of AutoTigAsset tokens held by the user for the given tigAsset.
*/
function userAutocompounding(address _user, address _tigAsset) public view returns (uint256) {
return IERC20(autoTigAsset[_tigAsset]).balanceOf(_user);
}
/**
* @dev Checks if a tigAsset is whitelisted.
* @param _tigAsset The address of the tigAsset to be checked.
* @return A boolean indicating whether the tigAsset is whitelisted.
*/
function isAssetWhitelisted(address _tigAsset) external view returns (bool) {
return assets.get(_tigAsset);
}
}
/**
* @title AutoTigAsset
* @dev A token contract representing AutoTigAsset tokens, which are minted and burned for users who enable autocompounding.
*/
contract AutoTigAsset is ERC20, IAutoTigAsset {
address public immutable underlying;
address public immutable factory;
/**
* @dev Creates AutoTigAsset tokens for a specific tigAsset.
* @param _tigAsset The address of the tigAsset to be represented by the AutoTigAsset tokens.
*/
constructor(
address _tigAsset
) ERC20(
string(abi.encodePacked("Autocompounding ", ERC20(_tigAsset).name())),
string(abi.encodePacked("auto", ERC20(_tigAsset).symbol()))
) {
require(_tigAsset != address(0), "ZeroAddress");
underlying = _tigAsset;
factory = msg.sender;
}
/**
* @dev Modifier to restrict minting and burning to the contract factory (TigrisLPStaking).
*/
modifier onlyFactory() {
require(msg.sender == factory, "Only factory");
_;
}
/**
* @dev Mints AutoTigAsset tokens to a specified address.
* @param _to The address to which the AutoTigAsset tokens will be minted.
* @param _amount The amount of AutoTigAsset tokens to mint.
* @notice Only the contract factory (TigrisLPStaking) can mint AutoTigAsset tokens.
*/
function mint(address _to, uint256 _amount) external onlyFactory {
_mint(_to, _amount);
}
/**
* @dev Burns AutoTigAsset tokens from a specified address.
* @param _from The address from which the AutoTigAsset tokens will be burned.
* @param _amount The amount of AutoTigAsset tokens to burn.
* @notice Only the contract factory (TigrisLPStaking) can burn AutoTigAsset tokens.
*/
function burn(address _from, uint256 _amount) external onlyFactory {
_burn(_from, _amount);
}
}// 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;
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":"address","name":"_treasury","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"}],"name":"AssetUnwhitelisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":true,"internalType":"contract IAutoTigAsset","name":"autoTigAsset","type":"address"}],"name":"AssetWhitelisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"newCap","type":"uint256"}],"name":"DepositCapUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"DepositFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"EarlyWithdrawFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"EarlyWithdrawal","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"EarlyWithdrawalEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"LPRewardClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"LPRewardDistributed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"NormalWithdrawFeeUpdated","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":"asset","type":"address"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newTreasury","type":"address"}],"name":"TreasuryUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"bool","name":"isAutocompounding","type":"bool"}],"name":"UserAutocompoundingUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawalCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"WithdrawalConfirmed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"WithdrawalInitiated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newPeriod","type":"uint256"}],"name":"WithdrawalPeriodUpdated","type":"event"},{"inputs":[],"name":"DIVISION_CONSTANT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_DEPOSIT_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_EARLY_WITHDRAW_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_NORMAL_WITHDRAW_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_WITHDRAWAL_PERIOD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_INITIAL_DEPOSIT","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":"","type":"address"}],"name":"autoTigAsset","outputs":[{"internalType":"contract IAutoTigAsset","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tigAsset","type":"address"}],"name":"cancelWithdrawal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tigAsset","type":"address"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"compoundedAssetValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tigAsset","type":"address"}],"name":"confirmWithdrawal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"depositCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"depositFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tigAsset","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"distribute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"earlyWithdrawFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tigAsset","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"earlyWithdrawal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"earlyWithdrawalEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tigAsset","type":"address"}],"name":"earlyWithdrawalMax","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tigAsset","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"initiateWithdrawal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tigAsset","type":"address"}],"name":"initiateWithdrawalMax","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tigAsset","type":"address"}],"name":"isAssetWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"isUserAutocompounding","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"normalWithdrawFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"address","name":"_tigAsset","type":"address"}],"name":"pending","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tigAsset","type":"address"},{"internalType":"bool","name":"_isAutocompounding","type":"bool"}],"name":"setAutocompounding","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tigAsset","type":"address"},{"internalType":"uint256","name":"_depositCap","type":"uint256"}],"name":"setDepositCap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_depositFee","type":"uint256"}],"name":"setDepositFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_earlyWithdrawFee","type":"uint256"}],"name":"setEarlyWithdrawFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_enabled","type":"bool"}],"name":"setEarlyWithdrawalEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"},{"internalType":"uint256","name":"_normalWithdrawFee","type":"uint256"}],"name":"setNormalWithdrawFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_treasury","type":"address"}],"name":"setTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_withdrawalPeriod","type":"uint256"}],"name":"setWithdrawalPeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tigAsset","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tigAsset","type":"address"}],"name":"totalAutocompounding","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tigAsset","type":"address"}],"name":"totalDeposited","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"totalPendingWithdrawal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"totalStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"address","name":"_tigAsset","type":"address"}],"name":"unwhitelistAsset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"address","name":"_tigAsset","type":"address"}],"name":"userAutocompounding","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"address","name":"_tigAsset","type":"address"}],"name":"userDeposited","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":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"userPendingWithdrawal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"userStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tigAsset","type":"address"},{"internalType":"uint256","name":"_initialDeposit","type":"uint256"}],"name":"whitelistAsset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"withdrawTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawalPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]Contract Creation Code
608060405262093a80600555633b9aca006007553480156200002057600080fd5b50604051620058dc380380620058dc83398101604081905262000043916200010d565b6200004e33620000bd565b6001600160a01b038116620000975760405162461bcd60e51b815260206004820152600b60248201526a5a65726f4164647265737360a81b604482015260640160405180910390fd5b600480546001600160a01b0319166001600160a01b03929092169190911790556200013f565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000602082840312156200012057600080fd5b81516001600160a01b03811681146200013857600080fd5b9392505050565b61578d806200014f6000396000f3fe60806040523480156200001157600080fd5b5060043610620003855760003560e01c80637da77d7711620001e1578063c22982f4116200010d578063f2fde38b11620000af578063f82a865a1162000086578063f82a865a1462000879578063f878369e1462000886578063fb932108146200089d578063ff05db8014620008b457600080fd5b8063f2fde38b1462000834578063f43e0ff2146200084b578063f66a2694146200086257600080fd5b8063ddc16b3111620000e4578063ddc16b3114620007fa578063e4fbf4041462000806578063f0f44260146200081d57600080fd5b8063c22982f414620007c0578063c6d87dd514620007d7578063c8393ba914620007e357600080fd5b80639bfd8d611162000183578063a80a7882116200015a578063a80a7882146200078a578063acd811eb1462000794578063adc9772e146200079f578063bca7093d14620007b657600080fd5b80639bfd8d6114620007375780639ce49697146200075a578063a4813488146200077d57600080fd5b8063940d0e9211620001b8578063940d0e9214620006f257806394e826161462000709578063973b294f146200072057600080fd5b80637da77d7714620006a55780638464160d14620006bc5780638da5cb5b14620006d357600080fd5b806344177b7711620002c157806366f6cb6811620002635780636df143e0116200023a5780636df143e01462000633578063715018a6146200064a5780637771dad5146200065457806378592386146200068257600080fd5b806366f6cb6814620005e457806367a5279314620005fb5780636986f92b146200060557600080fd5b806359dbace4116200029857806359dbace4146200059557806361d027b314620005ac57806366a049c114620005cd57600080fd5b806344177b771462000559578063490ae210146200056757806353055481146200057e57600080fd5b80632525343a116200032b578063388d89421162000302578063388d894214620005085780633e0db869146200052b578063411de867146200054257600080fd5b80632525343a14620004945780632ad876e014620004d6578063323f47e014620004e557600080fd5b80631e83409a11620003605780631e83409a146200042c5780631ed58ff0146200044357806320b71534146200047157600080fd5b8063160fa254146200038a57806319bc9ae814620003a35780631e71de8e14620003cd575b600080fd5b620003a16200039b36600462003f9b565b620008e2565b005b620003ba620003b436600462003fb9565b62000a51565b6040519081526020015b60405180910390f35b62000406620003de36600462003f9b565b60126020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620003c4565b620003a16200043d36600462003f9b565b62000b20565b620003ba6200045436600462003fb9565b600e60209081526000928352604080842090915290825290205481565b620003ba6200048236600462003f9b565b60136020526000908152604090205481565b620004c5620004a536600462003fb9565b600b60209081526000928352604080842090915290825290205460ff1681565b6040519015158152602001620003c4565b620003ba66038d7ea4c6800081565b620003ba620004f636600462003f9b565b600a6020526000908152604090205481565b620003ba6200051936600462003f9b565b60106020526000908152604090205481565b620003a16200053c36600462003f9b565b62000b2f565b620003a16200055336600462004000565b62000f31565b600854620004c59060ff1681565b620003a16200057836600462004027565b62000fa1565b620003ba6200058f36600462003f9b565b62001051565b620003a1620005a636600462004041565b620010bb565b600454620004069073ffffffffffffffffffffffffffffffffffffffff1681565b620003a1620005de36600462003f9b565b62001570565b620003a1620005f53660046200407d565b62001874565b620003ba60065481565b620003ba6200061636600462003fb9565b600d60209081526000928352604080842090915290825290205481565b620003a16200064436600462003f9b565b62001b68565b620003a162001b79565b620003ba6200066536600462003fb9565b600c60209081526000928352604080842090915290825290205481565b620003ba6200069336600462003f9b565b60116020526000908152604090205481565b620003ba620006b636600462003f9b565b62001b91565b620003ba620006cd36600462003fb9565b62001c35565b60005473ffffffffffffffffffffffffffffffffffffffff1662000406565b620003a1620007033660046200407d565b62001d09565b620003a16200071a3660046200407d565b620022b7565b620003a16200073136600462004027565b62002397565b620003ba6200074836600462003f9b565b60096020526000908152604090205481565b620003ba6200076b36600462003f9b565b60146020526000908152604090205481565b620003ba6402540be40081565b620003ba60075481565b620003ba62278d0081565b620003a1620007b03660046200407d565b62002446565b620003ba60055481565b620003a1620007d136600462004027565b620029b2565b620003ba6305f5e10081565b620003a1620007f43660046200407d565b62002a62565b620003ba639502f90081565b620004c56200081736600462003f9b565b62002f24565b620003a16200082e36600462003f9b565b62002f53565b620003a16200084536600462003f9b565b62003050565b620003a16200085c36600462003f9b565b6200310a565b620003ba6200087336600462003fb9565b6200311b565b620003ba64012a05f20081565b620003a1620008973660046200407d565b620031c1565b620003a1620008ae3660046200407d565b620032b1565b620003ba620008c536600462003fb9565b600f60209081526000928352604080842090915290825290205481565b620008ec620035ef565b73ffffffffffffffffffffffffffffffffffffffff81166200096f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f5a65726f4164647265737300000000000000000000000000000000000000000060448201526064015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811660009081526002602052604090205460ff1662000a00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f4e6f742077686974656c69737465640000000000000000000000000000000000604482015260640162000966565b62000a0d60018262003672565b60405173ffffffffffffffffffffffffffffffffffffffff8216907f8d9a07f76e4d5845bd20456b6c0e63682c0cdc217d5ce8688aa53bdfea6fbfae90600090a250565b73ffffffffffffffffffffffffffffffffffffffff8083166000908152600b6020908152604080832093851683529290529081205460ff161562000a985750600062000b1a565b73ffffffffffffffffffffffffffffffffffffffff8084166000818152600f60209081526040808320948716808452948252808320546010835281842054948452600c835281842095845294909152902054670de0b6b3a76400009162000aff91620040d9565b62000b0b9190620040f3565b62000b1791906200412f565b90505b92915050565b62000b2c338262003843565b50565b73ffffffffffffffffffffffffffffffffffffffff811662000bae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f5a65726f41646472657373000000000000000000000000000000000000000000604482015260640162000966565b336000908152600d6020908152604080832073ffffffffffffffffffffffffffffffffffffffff851684529091528120549081900362000c4b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4e6f7468696e6720746f2063616e63656c000000000000000000000000000000604482015260640162000966565b62000c57338362003843565b336000908152600d6020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684528252808320839055600a9091528120805483929062000ca39084906200412f565b9091555050336000908152600b6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915290205460ff161562000dcc5773ffffffffffffffffffffffffffffffffffffffff821660009081526011602052604081205462000d1c83670de0b6b3a7640000620040d9565b62000d289190620040f3565b73ffffffffffffffffffffffffffffffffffffffff848116600090815260126020526040908190205490517f40c10f190000000000000000000000000000000000000000000000000000000081523360048201526024810184905292935016906340c10f1990604401600060405180830381600087803b15801562000dac57600080fd5b505af115801562000dc1573d6000803e3d6000fd5b505050505062000edf565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600960205260408120805483929062000e0390849062004145565b9091555050336000908152600c6020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091528120805483929062000e4a90849062004145565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600081815260106020908152604080832054338452600c835281842094845293909152902054670de0b6b3a76400009162000ea191620040d9565b62000ead9190620040f3565b336000908152600f6020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091529020555b604051818152339073ffffffffffffffffffffffffffffffffffffffff8416907f75f1e929bc3763cbb44e9f41114fbc63fb4dc8b10ecb29e801d0970fddb30779906020015b60405180910390a35050565b62000f3b620035ef565b600880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168215159081179091556040519081527f4279c46dba1a52aacf75088463f77f44ab1af75ca8b822f3cdd4b92043068540906020015b60405180910390a150565b62000fab620035ef565b6305f5e1008111156200101b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f46656520746f6f20686967680000000000000000000000000000000000000000604482015260640162000966565b60068190556040518181527f206dd15151fcc83315419fbe53a71fcf9c09da803767d3dd05f7874e1b9bf6459060200162000f96565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600960209081526040808320546011909252822054670de0b6b3a764000090620010978562001b91565b620010a39190620040d9565b620010af9190620040f3565b62000b1a919062004145565b73ffffffffffffffffffffffffffffffffffffffff82166200113a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f5a65726f41646472657373000000000000000000000000000000000000000000604482015260640162000966565b62001146338362003843565b336000908152600b6020908152604080832073ffffffffffffffffffffffffffffffffffffffff86168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168215801591909117909155620013175773ffffffffffffffffffffffffffffffffffffffff8216600081815260116020908152604080832054338452600c835281842094845293909152812054909190620011fe90670de0b6b3a7640000620040d9565b6200120a9190620040f3565b336000908152600c6020908152604080832073ffffffffffffffffffffffffffffffffffffffff881684528252808320546009909252822080549394509092909190620012599084906200412f565b9091555050336000818152600c6020908152604080832073ffffffffffffffffffffffffffffffffffffffff88811685529083528184208490556012909252918290205491517f40c10f1900000000000000000000000000000000000000000000000000000000815260048101939093526024830184905216906340c10f1990604401600060405180830381600087803b158015620012f757600080fd5b505af11580156200130c573d6000803e3d6000fd5b505050505062001523565b60006200132533846200311b565b73ffffffffffffffffffffffffffffffffffffffff841660009081526011602052604081205491925090670de0b6b3a764000090620013659084620040d9565b620013719190620040f3565b73ffffffffffffffffffffffffffffffffffffffff858116600090815260126020526040908190205490517f9dc29fac000000000000000000000000000000000000000000000000000000008152336004820152602481018690529293501690639dc29fac90604401600060405180830381600087803b158015620013f557600080fd5b505af11580156200140a573d6000803e3d6000fd5b50505073ffffffffffffffffffffffffffffffffffffffff8516600090815260106020526040902054670de0b6b3a764000091506200144a9083620040d9565b620014569190620040f3565b336000908152600f6020908152604080832073ffffffffffffffffffffffffffffffffffffffff89168452909152812080549091906200149890849062004145565b909155505073ffffffffffffffffffffffffffffffffffffffff841660009081526009602052604081208054839290620014d490849062004145565b9091555050336000908152600c6020908152604080832073ffffffffffffffffffffffffffffffffffffffff88168452909152812080548392906200151b90849062004145565b909155505050505b604051811515815273ffffffffffffffffffffffffffffffffffffffff83169033907f5db09964bad0d5076980dd067a7b85c0e2223ab2aca793a338b961baf93ec2af9060200162000f25565b73ffffffffffffffffffffffffffffffffffffffff8116620015ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f5a65726f41646472657373000000000000000000000000000000000000000000604482015260640162000966565b336000908152600d6020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152812054908190036200168c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4e6f7468696e6720746f20776974686472617700000000000000000000000000604482015260640162000966565b336000908152600e6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915290205442101562001728576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5769746864726177616c206e6f74207265616479000000000000000000000000604482015260640162000966565b336000908152600d6020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684528252808320839055600a90915281208054839290620017749084906200412f565b909155505073ffffffffffffffffffffffffffffffffffffffff82166000908152601460205260408120546402540be40090620017b29084620040d9565b620017be9190620040f3565b9050620017cc81836200412f565b600454909250620017f89073ffffffffffffffffffffffffffffffffffffffff858116911683620039af565b6200181b73ffffffffffffffffffffffffffffffffffffffff84163384620039af565b6040805183815260208101839052339173ffffffffffffffffffffffffffffffffffffffff8616917f2c827aaf63a2d33ada9256a258929e98957e25cc6b122c5d81fafa606249b3f291015b60405180910390a3505050565b6200187e620035ef565b73ffffffffffffffffffffffffffffffffffffffff8216620018fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f5a65726f41646472657373000000000000000000000000000000000000000000604482015260640162000966565b73ffffffffffffffffffffffffffffffffffffffff821660009081526002602052604090205460ff16156200198f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f416c72656164792077686974656c697374656400000000000000000000000000604482015260640162000966565b6200199c60018362003a8a565b73ffffffffffffffffffffffffffffffffffffffff808316600090815260126020526040902054168062001b095766038d7ea4c6800082101562001a3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f496e697469616c206465706f73697420746f6f20736d616c6c00000000000000604482015260640162000966565b8260405162001a4c9062003f63565b73ffffffffffffffffffffffffffffffffffffffff9091168152602001604051809103906000f08015801562001a86573d6000803e3d6000fd5b5073ffffffffffffffffffffffffffffffffffffffff848116600090815260126020908152604080832080547fffffffffffffffffffffffff000000000000000000000000000000000000000016948616949094179093556011905220670de0b6b3a76400009055905062001afd836001620010bb565b62001b09838362002446565b8073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3f67845b0831549d6cdea73c455caaeb3ddd0b14039c70f92cbd819cb956c7f60405160405180910390a3505050565b62000b2c81620007f4338462001c35565b62001b83620035ef565b62001b8f600062003b53565b565b73ffffffffffffffffffffffffffffffffffffffff80821660009081526012602090815260408083205481517f18160ddd0000000000000000000000000000000000000000000000000000000081529151939416926318160ddd926004808401939192918290030181865afa15801562001c0f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000b1a91906200415b565b73ffffffffffffffffffffffffffffffffffffffff8083166000908152600b6020908152604080832093851683529290529081205460ff161562001ccf5773ffffffffffffffffffffffffffffffffffffffff8216600090815260116020526040902054670de0b6b3a76400009062001caf85856200311b565b62001cbb9190620040d9565b62001cc79190620040f3565b905062000b1a565b5073ffffffffffffffffffffffffffffffffffffffff8083166000908152600c602090815260408083209385168352929052205462000b1a565b60085460ff1662001d77576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4561726c79207769746864726177616c2064697361626c656400000000000000604482015260640162000966565b73ffffffffffffffffffffffffffffffffffffffff821662001df6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f5a65726f41646472657373000000000000000000000000000000000000000000604482015260640162000966565b8060000362001e62576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e2030000000604482015260640162000966565b8062001e6f338462001c35565b101562001ed9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4e6f7420656e6f756768207374616b6564000000000000000000000000000000604482015260640162000966565b336000908152600d6020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091529020541562001f73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f5769746864726177616c20616c726561647920696e6974696174656400000000604482015260640162000966565b62001f7f338362003843565b336000908152600b6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915290205460ff1615620020a35773ffffffffffffffffffffffffffffffffffffffff821660009081526011602052604081205462001ff383670de0b6b3a7640000620040d9565b62001fff9190620040f3565b73ffffffffffffffffffffffffffffffffffffffff848116600090815260126020526040908190205490517f9dc29fac000000000000000000000000000000000000000000000000000000008152336004820152602481018490529293501690639dc29fac90604401600060405180830381600087803b1580156200208357600080fd5b505af115801562002098573d6000803e3d6000fd5b5050505050620021b6565b73ffffffffffffffffffffffffffffffffffffffff821660009081526009602052604081208054839290620020da9084906200412f565b9091555050336000908152600c6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915281208054839290620021219084906200412f565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600081815260106020908152604080832054338452600c835281842094845293909152902054670de0b6b3a7640000916200217891620040d9565b620021849190620040f3565b336000908152600f6020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091529020555b73ffffffffffffffffffffffffffffffffffffffff82166000908152601460205260408120546007546402540be40091620021f19162004145565b620021fd9084620040d9565b620022099190620040f3565b90506200221781836200412f565b600454909250620022439073ffffffffffffffffffffffffffffffffffffffff858116911683620039af565b6200226673ffffffffffffffffffffffffffffffffffffffff84163384620039af565b6040805183815260208101839052339173ffffffffffffffffffffffffffffffffffffffff8616917f293037788d87ac1cd6e14a58daea87cdc73495ac74b7be45eabf2ea86d256697910162001867565b620022c1620035ef565b64012a05f20081111562002332576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f46656520746f6f20686967680000000000000000000000000000000000000000604482015260640162000966565b73ffffffffffffffffffffffffffffffffffffffff8216600081815260146020908152604091829020849055815192835282018390527f6c8b1187e7b5f6818a7d98d4aa5cb3a6efdd96a57f2e3cbd5da405dfd1a91997910160405180910390a15050565b620023a1620035ef565b62278d0081111562002410576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f5769746864726177616c20706572696f6420746f6f206c6f6e67000000000000604482015260640162000966565b60058190556040518181527f4157b30b99fc9ed1b54c707f60552f93b22a74b0859af295ae63994b387006ee9060200162000f96565b73ffffffffffffffffffffffffffffffffffffffff8216620024c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f5a65726f41646472657373000000000000000000000000000000000000000000604482015260640162000966565b8060000362002531576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f5a65726f416d6f756e7400000000000000000000000000000000000000000000604482015260640162000966565b73ffffffffffffffffffffffffffffffffffffffff821660009081526002602052604090205460ff16620025c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4173736574206e6f7420616c6c6f776564000000000000000000000000000000604482015260640162000966565b600060065460001462002602576402540be40060065483620025e59190620040d9565b620025f19190620040f3565b9050620025ff81836200412f565b91505b73ffffffffffffffffffffffffffffffffffffffff8316600090815260136020908152604080832054600a909252909120548390620026418662001051565b6200264d919062004145565b62002659919062004145565b1115620026c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4465706f73697420636170206578636565646564000000000000000000000000604482015260640162000966565b620026cf338462003843565b620027013330620026e1848662004145565b73ffffffffffffffffffffffffffffffffffffffff871692919062003bc8565b6004546200272a9073ffffffffffffffffffffffffffffffffffffffff858116911683620039af565b336000908152600b6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915290205460ff16156200284e5773ffffffffffffffffffffffffffffffffffffffff83166000908152601160205260408120546200279e84670de0b6b3a7640000620040d9565b620027aa9190620040f3565b73ffffffffffffffffffffffffffffffffffffffff858116600090815260126020526040908190205490517f40c10f190000000000000000000000000000000000000000000000000000000081523360048201526024810184905292935016906340c10f1990604401600060405180830381600087803b1580156200282e57600080fd5b505af115801562002843573d6000803e3d6000fd5b505050505062002961565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260096020526040812080548492906200288590849062004145565b9091555050336000908152600c6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281208054849290620028cc90849062004145565b909155505073ffffffffffffffffffffffffffffffffffffffff8316600081815260106020908152604080832054338452600c835281842094845293909152902054670de0b6b3a7640000916200292391620040d9565b6200292f9190620040f3565b336000908152600f6020908152604080832073ffffffffffffffffffffffffffffffffffffffff881684529091529020555b6040805183815260208101839052339173ffffffffffffffffffffffffffffffffffffffff8616917f6c86f3fd5118b3aa8bb4f389a617046de0a3d3d477de1a1673d227f802f616dc910162001867565b620029bc620035ef565b639502f90081111562002a2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f46656520746f6f20686967680000000000000000000000000000000000000000604482015260640162000966565b60078190556040518181527f864cabeb83698b194f9b49e7f58558d83cd8e635575ba53f511f37c834ece71c9060200162000f96565b73ffffffffffffffffffffffffffffffffffffffff821662002ae1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f5a65726f41646472657373000000000000000000000000000000000000000000604482015260640162000966565b8060000362002b4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e2030000000604482015260640162000966565b8062002b5a338462001c35565b101562002bc4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4e6f7420656e6f756768207374616b6564000000000000000000000000000000604482015260640162000966565b62002bd0338362003843565b336000908152600b6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915290205460ff161562002cf45773ffffffffffffffffffffffffffffffffffffffff821660009081526011602052604081205462002c4483670de0b6b3a7640000620040d9565b62002c509190620040f3565b73ffffffffffffffffffffffffffffffffffffffff848116600090815260126020526040908190205490517f9dc29fac000000000000000000000000000000000000000000000000000000008152336004820152602481018490529293501690639dc29fac90604401600060405180830381600087803b15801562002cd457600080fd5b505af115801562002ce9573d6000803e3d6000fd5b505050505062002e07565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600960205260408120805483929062002d2b9084906200412f565b9091555050336000908152600c6020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091528120805483929062002d729084906200412f565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600081815260106020908152604080832054338452600c835281842094845293909152902054670de0b6b3a76400009162002dc991620040d9565b62002dd59190620040f3565b336000908152600f6020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091529020555b336000908152600d6020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091528120805483929062002e4990849062004145565b909155505073ffffffffffffffffffffffffffffffffffffffff82166000908152600a60205260408120805483929062002e8590849062004145565b909155505060055462002e99904262004145565b336000818152600e6020908152604080832073ffffffffffffffffffffffffffffffffffffffff881680855290835292819020859055805186815291820194909452919290917f2e16c360bf25f9193c8e78b0fcdf02bacfd34fd98ec9fe4aa2549e15346dafd2910160405180910390a360055460000362002f205762002f208262001570565b5050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526002602052604081205460ff1662000b1a565b62002f5d620035ef565b73ffffffffffffffffffffffffffffffffffffffff811662002fdc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f5a65726f41646472657373000000000000000000000000000000000000000000604482015260640162000966565b600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d19060200162000f96565b6200305a620035ef565b73ffffffffffffffffffffffffffffffffffffffff8116620030ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840162000966565b62000b2c8162003b53565b62000b2c8162000703338462001c35565b73ffffffffffffffffffffffffffffffffffffffff8181166000908152601260205260408082205490517f70a082310000000000000000000000000000000000000000000000000000000081528584166004820152919216906370a0823190602401602060405180830381865afa1580156200319b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000b1791906200415b565b620031cb620035ef565b73ffffffffffffffffffffffffffffffffffffffff82166200324a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f5a65726f41646472657373000000000000000000000000000000000000000000604482015260640162000966565b73ffffffffffffffffffffffffffffffffffffffff821660008181526013602052604090819020839055517fdb0e031f017e9837f619ff44f6ce88716d74b5a62af3de735b952fb47887d96590620032a59084815260200190565b60405180910390a25050565b73ffffffffffffffffffffffffffffffffffffffff821662003330576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f5a65726f41646472657373000000000000000000000000000000000000000000604482015260640162000966565b73ffffffffffffffffffffffffffffffffffffffff821660009081526002602052604090205460ff1615806200336e57506200336c8262001051565b155b8062003378575080155b1562003382575050565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201523060248201526044810182905273ffffffffffffffffffffffffffffffffffffffff8316906323b872dd906064016020604051808303816000875af192505050801562003438575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252620034359181019062004175565b60015b62003441575050565b5060006200344f8362001051565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260096020526040902054620034819084620040d9565b6200348d9190620040f3565b905060006200349d82846200412f565b90508115620035295773ffffffffffffffffffffffffffffffffffffffff8416600090815260096020526040902054620034e083670de0b6b3a7640000620040d9565b620034ec9190620040f3565b73ffffffffffffffffffffffffffffffffffffffff8516600090815260106020526040812080549091906200352390849062004145565b90915550505b801562003598576200353b8462001b91565b6200354f82670de0b6b3a7640000620040d9565b6200355b9190620040f3565b73ffffffffffffffffffffffffffffffffffffffff8516600090815260116020526040812080549091906200359290849062004145565b90915550505b8373ffffffffffffffffffffffffffffffffffffffff167fea310f979febc9b4af7c2bc0ae7bf01599119a08a90d4200cd0e2548fcf601c984604051620035e191815260200190565b60405180910390a250505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331462001b8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000966565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604090205460ff161562002f205773ffffffffffffffffffffffffffffffffffffffff8116600090815260018084016020908152604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905560028601909152822054845490929185916200371191906200412f565b8154811062003724576200372462004195565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff90811680845260028801909252604080842086905590861683528220919091558454909150819085908490811062003783576200378362004195565b600091825260209091200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790558354849080620037e557620037e5620041c4565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550505050565b73ffffffffffffffffffffffffffffffffffffffff8116620038c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f5a65726f41646472657373000000000000000000000000000000000000000000604482015260640162000966565b6000620038d0838362000a51565b905080600003620038e057505050565b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600f60209081526040808320938616835292905290812080548392906200392690849062004145565b909155506200394f905073ffffffffffffffffffffffffffffffffffffffff83168483620039af565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fd5c7f00f812b57a4de7d2be4d224a696e313e9a810ff86cdeb6caf3ac9d0d266836040516200186791815260200190565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905262003a859084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915262003c2e565b505050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604090205460ff1662002f205773ffffffffffffffffffffffffffffffffffffffff16600081815260018381016020908152604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016841790558554600287018352908420819055918201855593825292902090910180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169091179055565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905262003c289085907f23b872dd000000000000000000000000000000000000000000000000000000009060840162003a02565b50505050565b600062003c92826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1662003d419092919063ffffffff16565b80519091501562003a85578080602001905181019062003cb3919062004175565b62003a85576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840162000966565b606062003d52848460008562003d5a565b949350505050565b60608247101562003dee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840162000966565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405162003e19919062004219565b60006040518083038185875af1925050503d806000811462003e58576040519150601f19603f3d011682016040523d82523d6000602084013e62003e5d565b606091505b509150915062003e708783838762003e7b565b979650505050505050565b6060831562003f1657825160000362003f0e5773ffffffffffffffffffffffffffffffffffffffff85163b62003f0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000966565b508162003d52565b62003d52838381511562003f2d5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000966919062004237565b6114cd806200428b83390190565b803573ffffffffffffffffffffffffffffffffffffffff8116811462003f9657600080fd5b919050565b60006020828403121562003fae57600080fd5b62000b178262003f71565b6000806040838503121562003fcd57600080fd5b62003fd88362003f71565b915062003fe86020840162003f71565b90509250929050565b801515811462000b2c57600080fd5b6000602082840312156200401357600080fd5b8135620040208162003ff1565b9392505050565b6000602082840312156200403a57600080fd5b5035919050565b600080604083850312156200405557600080fd5b620040608362003f71565b91506020830135620040728162003ff1565b809150509250929050565b600080604083850312156200409157600080fd5b6200409c8362003f71565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141762000b1a5762000b1a620040aa565b6000826200412a577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b8181038181111562000b1a5762000b1a620040aa565b8082018082111562000b1a5762000b1a620040aa565b6000602082840312156200416e57600080fd5b5051919050565b6000602082840312156200418857600080fd5b8151620040208162003ff1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60005b8381101562004210578181015183820152602001620041f6565b50506000910152565b600082516200422d818460208701620041f3565b9190910192915050565b602081526000825180602084015262004258816040850160208701620041f3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe60c06040523480156200001157600080fd5b50604051620014cd380380620014cd8339810160408190526200003491620001c8565b806001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa15801562000073573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200009d919081019062000236565b604051602001620000af9190620002ee565b604051602081830303815290604052816001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620000fd573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000127919081019062000236565b60405160200162000139919062000328565b60408051601f198184030181529190526003620001578382620003e5565b506004620001668282620003e5565b5050506001600160a01b038116620001b25760405162461bcd60e51b815260206004820152600b60248201526a5a65726f4164647265737360a81b604482015260640160405180910390fd5b6001600160a01b03166080523360a052620004b1565b600060208284031215620001db57600080fd5b81516001600160a01b0381168114620001f357600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b60005b838110156200022d57818101518382015260200162000213565b50506000910152565b6000602082840312156200024957600080fd5b81516001600160401b03808211156200026157600080fd5b818401915084601f8301126200027657600080fd5b8151818111156200028b576200028b620001fa565b604051601f8201601f19908116603f01168101908382118183101715620002b657620002b6620001fa565b81604052828152876020848701011115620002d057600080fd5b620002e383602083016020880162000210565b979650505050505050565b6f020baba37b1b7b6b837bab73234b733960851b8152600082516200031b81601085016020870162000210565b9190910160100192915050565b636175746f60e01b8152600082516200034981600485016020870162000210565b9190910160040192915050565b600181811c908216806200036b57607f821691505b6020821081036200038c57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620003e057600081815260208120601f850160051c81016020861015620003bb5750805b601f850160051c820191505b81811015620003dc57828155600101620003c7565b5050505b505050565b81516001600160401b03811115620004015762000401620001fa565b620004198162000412845462000356565b8462000392565b602080601f831160018114620004515760008415620004385750858301515b600019600386901b1c1916600185901b178555620003dc565b600085815260208120601f198616915b82811015620004825788860151825594840194600190910190840162000461565b5085821015620004a15787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a051610fe8620004e56000396000818161025f015281816103fb01526104bc0152600061019c0152610fe86000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80636f307dc311610097578063a457c2d711610066578063a457c2d714610234578063a9059cbb14610247578063c45a01551461025a578063dd62ed3e1461028157600080fd5b80636f307dc31461019757806370a08231146101e357806395d89b41146102195780639dc29fac1461022157600080fd5b806323b872dd116100d357806323b872dd1461014d578063313ce56714610160578063395093511461016f57806340c10f191461018257600080fd5b806306fdde03146100fa578063095ea7b31461011857806318160ddd1461013b575b600080fd5b6101026102c7565b60405161010f9190610dd5565b60405180910390f35b61012b610126366004610e6a565b610359565b604051901515815260200161010f565b6002545b60405190815260200161010f565b61012b61015b366004610e94565b610373565b6040516012815260200161010f565b61012b61017d366004610e6a565b610397565b610195610190366004610e6a565b6103e3565b005b6101be7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161010f565b61013f6101f1366004610ed0565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b610102610495565b61019561022f366004610e6a565b6104a4565b61012b610242366004610e6a565b61054d565b61012b610255366004610e6a565b61061e565b6101be7f000000000000000000000000000000000000000000000000000000000000000081565b61013f61028f366004610ef2565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6060600380546102d690610f25565b80601f016020809104026020016040519081016040528092919081815260200182805461030290610f25565b801561034f5780601f106103245761010080835404028352916020019161034f565b820191906000526020600020905b81548152906001019060200180831161033257829003601f168201915b5050505050905090565b60003361036781858561062c565b60019150505b92915050565b6000336103818582856107e0565b61038c8585856108b7565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919061036790829086906103de908790610f78565b61062c565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610487576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4f6e6c7920666163746f7279000000000000000000000000000000000000000060448201526064015b60405180910390fd5b6104918282610b26565b5050565b6060600480546102d690610f25565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610543576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4f6e6c7920666163746f72790000000000000000000000000000000000000000604482015260640161047e565b6104918282610c19565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015610611576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f000000000000000000000000000000000000000000000000000000606482015260840161047e565b61038c828686840361062c565b6000336103678185856108b7565b73ffffffffffffffffffffffffffffffffffffffff83166106ce576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015260840161047e565b73ffffffffffffffffffffffffffffffffffffffff8216610771576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015260840161047e565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146108b157818110156108a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161047e565b6108b1848484840361062c565b50505050565b73ffffffffffffffffffffffffffffffffffffffff831661095a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f6472657373000000000000000000000000000000000000000000000000000000606482015260840161047e565b73ffffffffffffffffffffffffffffffffffffffff82166109fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015260840161047e565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610ab3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e63650000000000000000000000000000000000000000000000000000606482015260840161047e565b73ffffffffffffffffffffffffffffffffffffffff848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a36108b1565b73ffffffffffffffffffffffffffffffffffffffff8216610ba3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161047e565b8060026000828254610bb59190610f78565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8216610cbc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f7300000000000000000000000000000000000000000000000000000000000000606482015260840161047e565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015610d72576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f6365000000000000000000000000000000000000000000000000000000000000606482015260840161047e565b73ffffffffffffffffffffffffffffffffffffffff83166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91016107d3565b600060208083528351808285015260005b81811015610e0257858101830151858201604001528201610de6565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610e6557600080fd5b919050565b60008060408385031215610e7d57600080fd5b610e8683610e41565b946020939093013593505050565b600080600060608486031215610ea957600080fd5b610eb284610e41565b9250610ec060208501610e41565b9150604084013590509250925092565b600060208284031215610ee257600080fd5b610eeb82610e41565b9392505050565b60008060408385031215610f0557600080fd5b610f0e83610e41565b9150610f1c60208401610e41565b90509250929050565b600181811c90821680610f3957607f821691505b602082108103610f72577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b8082018082111561036d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fdfea2646970667358221220ce939e86e4dcfc9caa55fda8d25443a6063624b778e98902bc48352e294f37b464736f6c63430008130033a264697066735822122072436d745565bbb533e0b7b74755ff3cf4916f91ecbe6004126344cb06ac618d64736f6c63430008130033000000000000000000000000f416c2b41fb6c592c9ba7cb6b2f985ed593a51d7
Deployed Bytecode
0x60806040523480156200001157600080fd5b5060043610620003855760003560e01c80637da77d7711620001e1578063c22982f4116200010d578063f2fde38b11620000af578063f82a865a1162000086578063f82a865a1462000879578063f878369e1462000886578063fb932108146200089d578063ff05db8014620008b457600080fd5b8063f2fde38b1462000834578063f43e0ff2146200084b578063f66a2694146200086257600080fd5b8063ddc16b3111620000e4578063ddc16b3114620007fa578063e4fbf4041462000806578063f0f44260146200081d57600080fd5b8063c22982f414620007c0578063c6d87dd514620007d7578063c8393ba914620007e357600080fd5b80639bfd8d611162000183578063a80a7882116200015a578063a80a7882146200078a578063acd811eb1462000794578063adc9772e146200079f578063bca7093d14620007b657600080fd5b80639bfd8d6114620007375780639ce49697146200075a578063a4813488146200077d57600080fd5b8063940d0e9211620001b8578063940d0e9214620006f257806394e826161462000709578063973b294f146200072057600080fd5b80637da77d7714620006a55780638464160d14620006bc5780638da5cb5b14620006d357600080fd5b806344177b7711620002c157806366f6cb6811620002635780636df143e0116200023a5780636df143e01462000633578063715018a6146200064a5780637771dad5146200065457806378592386146200068257600080fd5b806366f6cb6814620005e457806367a5279314620005fb5780636986f92b146200060557600080fd5b806359dbace4116200029857806359dbace4146200059557806361d027b314620005ac57806366a049c114620005cd57600080fd5b806344177b771462000559578063490ae210146200056757806353055481146200057e57600080fd5b80632525343a116200032b578063388d89421162000302578063388d894214620005085780633e0db869146200052b578063411de867146200054257600080fd5b80632525343a14620004945780632ad876e014620004d6578063323f47e014620004e557600080fd5b80631e83409a11620003605780631e83409a146200042c5780631ed58ff0146200044357806320b71534146200047157600080fd5b8063160fa254146200038a57806319bc9ae814620003a35780631e71de8e14620003cd575b600080fd5b620003a16200039b36600462003f9b565b620008e2565b005b620003ba620003b436600462003fb9565b62000a51565b6040519081526020015b60405180910390f35b62000406620003de36600462003f9b565b60126020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620003c4565b620003a16200043d36600462003f9b565b62000b20565b620003ba6200045436600462003fb9565b600e60209081526000928352604080842090915290825290205481565b620003ba6200048236600462003f9b565b60136020526000908152604090205481565b620004c5620004a536600462003fb9565b600b60209081526000928352604080842090915290825290205460ff1681565b6040519015158152602001620003c4565b620003ba66038d7ea4c6800081565b620003ba620004f636600462003f9b565b600a6020526000908152604090205481565b620003ba6200051936600462003f9b565b60106020526000908152604090205481565b620003a16200053c36600462003f9b565b62000b2f565b620003a16200055336600462004000565b62000f31565b600854620004c59060ff1681565b620003a16200057836600462004027565b62000fa1565b620003ba6200058f36600462003f9b565b62001051565b620003a1620005a636600462004041565b620010bb565b600454620004069073ffffffffffffffffffffffffffffffffffffffff1681565b620003a1620005de36600462003f9b565b62001570565b620003a1620005f53660046200407d565b62001874565b620003ba60065481565b620003ba6200061636600462003fb9565b600d60209081526000928352604080842090915290825290205481565b620003a16200064436600462003f9b565b62001b68565b620003a162001b79565b620003ba6200066536600462003fb9565b600c60209081526000928352604080842090915290825290205481565b620003ba6200069336600462003f9b565b60116020526000908152604090205481565b620003ba620006b636600462003f9b565b62001b91565b620003ba620006cd36600462003fb9565b62001c35565b60005473ffffffffffffffffffffffffffffffffffffffff1662000406565b620003a1620007033660046200407d565b62001d09565b620003a16200071a3660046200407d565b620022b7565b620003a16200073136600462004027565b62002397565b620003ba6200074836600462003f9b565b60096020526000908152604090205481565b620003ba6200076b36600462003f9b565b60146020526000908152604090205481565b620003ba6402540be40081565b620003ba60075481565b620003ba62278d0081565b620003a1620007b03660046200407d565b62002446565b620003ba60055481565b620003a1620007d136600462004027565b620029b2565b620003ba6305f5e10081565b620003a1620007f43660046200407d565b62002a62565b620003ba639502f90081565b620004c56200081736600462003f9b565b62002f24565b620003a16200082e36600462003f9b565b62002f53565b620003a16200084536600462003f9b565b62003050565b620003a16200085c36600462003f9b565b6200310a565b620003ba6200087336600462003fb9565b6200311b565b620003ba64012a05f20081565b620003a1620008973660046200407d565b620031c1565b620003a1620008ae3660046200407d565b620032b1565b620003ba620008c536600462003fb9565b600f60209081526000928352604080842090915290825290205481565b620008ec620035ef565b73ffffffffffffffffffffffffffffffffffffffff81166200096f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f5a65726f4164647265737300000000000000000000000000000000000000000060448201526064015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811660009081526002602052604090205460ff1662000a00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f4e6f742077686974656c69737465640000000000000000000000000000000000604482015260640162000966565b62000a0d60018262003672565b60405173ffffffffffffffffffffffffffffffffffffffff8216907f8d9a07f76e4d5845bd20456b6c0e63682c0cdc217d5ce8688aa53bdfea6fbfae90600090a250565b73ffffffffffffffffffffffffffffffffffffffff8083166000908152600b6020908152604080832093851683529290529081205460ff161562000a985750600062000b1a565b73ffffffffffffffffffffffffffffffffffffffff8084166000818152600f60209081526040808320948716808452948252808320546010835281842054948452600c835281842095845294909152902054670de0b6b3a76400009162000aff91620040d9565b62000b0b9190620040f3565b62000b1791906200412f565b90505b92915050565b62000b2c338262003843565b50565b73ffffffffffffffffffffffffffffffffffffffff811662000bae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f5a65726f41646472657373000000000000000000000000000000000000000000604482015260640162000966565b336000908152600d6020908152604080832073ffffffffffffffffffffffffffffffffffffffff851684529091528120549081900362000c4b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4e6f7468696e6720746f2063616e63656c000000000000000000000000000000604482015260640162000966565b62000c57338362003843565b336000908152600d6020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684528252808320839055600a9091528120805483929062000ca39084906200412f565b9091555050336000908152600b6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915290205460ff161562000dcc5773ffffffffffffffffffffffffffffffffffffffff821660009081526011602052604081205462000d1c83670de0b6b3a7640000620040d9565b62000d289190620040f3565b73ffffffffffffffffffffffffffffffffffffffff848116600090815260126020526040908190205490517f40c10f190000000000000000000000000000000000000000000000000000000081523360048201526024810184905292935016906340c10f1990604401600060405180830381600087803b15801562000dac57600080fd5b505af115801562000dc1573d6000803e3d6000fd5b505050505062000edf565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600960205260408120805483929062000e0390849062004145565b9091555050336000908152600c6020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091528120805483929062000e4a90849062004145565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600081815260106020908152604080832054338452600c835281842094845293909152902054670de0b6b3a76400009162000ea191620040d9565b62000ead9190620040f3565b336000908152600f6020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091529020555b604051818152339073ffffffffffffffffffffffffffffffffffffffff8416907f75f1e929bc3763cbb44e9f41114fbc63fb4dc8b10ecb29e801d0970fddb30779906020015b60405180910390a35050565b62000f3b620035ef565b600880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168215159081179091556040519081527f4279c46dba1a52aacf75088463f77f44ab1af75ca8b822f3cdd4b92043068540906020015b60405180910390a150565b62000fab620035ef565b6305f5e1008111156200101b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f46656520746f6f20686967680000000000000000000000000000000000000000604482015260640162000966565b60068190556040518181527f206dd15151fcc83315419fbe53a71fcf9c09da803767d3dd05f7874e1b9bf6459060200162000f96565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600960209081526040808320546011909252822054670de0b6b3a764000090620010978562001b91565b620010a39190620040d9565b620010af9190620040f3565b62000b1a919062004145565b73ffffffffffffffffffffffffffffffffffffffff82166200113a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f5a65726f41646472657373000000000000000000000000000000000000000000604482015260640162000966565b62001146338362003843565b336000908152600b6020908152604080832073ffffffffffffffffffffffffffffffffffffffff86168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168215801591909117909155620013175773ffffffffffffffffffffffffffffffffffffffff8216600081815260116020908152604080832054338452600c835281842094845293909152812054909190620011fe90670de0b6b3a7640000620040d9565b6200120a9190620040f3565b336000908152600c6020908152604080832073ffffffffffffffffffffffffffffffffffffffff881684528252808320546009909252822080549394509092909190620012599084906200412f565b9091555050336000818152600c6020908152604080832073ffffffffffffffffffffffffffffffffffffffff88811685529083528184208490556012909252918290205491517f40c10f1900000000000000000000000000000000000000000000000000000000815260048101939093526024830184905216906340c10f1990604401600060405180830381600087803b158015620012f757600080fd5b505af11580156200130c573d6000803e3d6000fd5b505050505062001523565b60006200132533846200311b565b73ffffffffffffffffffffffffffffffffffffffff841660009081526011602052604081205491925090670de0b6b3a764000090620013659084620040d9565b620013719190620040f3565b73ffffffffffffffffffffffffffffffffffffffff858116600090815260126020526040908190205490517f9dc29fac000000000000000000000000000000000000000000000000000000008152336004820152602481018690529293501690639dc29fac90604401600060405180830381600087803b158015620013f557600080fd5b505af11580156200140a573d6000803e3d6000fd5b50505073ffffffffffffffffffffffffffffffffffffffff8516600090815260106020526040902054670de0b6b3a764000091506200144a9083620040d9565b620014569190620040f3565b336000908152600f6020908152604080832073ffffffffffffffffffffffffffffffffffffffff89168452909152812080549091906200149890849062004145565b909155505073ffffffffffffffffffffffffffffffffffffffff841660009081526009602052604081208054839290620014d490849062004145565b9091555050336000908152600c6020908152604080832073ffffffffffffffffffffffffffffffffffffffff88168452909152812080548392906200151b90849062004145565b909155505050505b604051811515815273ffffffffffffffffffffffffffffffffffffffff83169033907f5db09964bad0d5076980dd067a7b85c0e2223ab2aca793a338b961baf93ec2af9060200162000f25565b73ffffffffffffffffffffffffffffffffffffffff8116620015ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f5a65726f41646472657373000000000000000000000000000000000000000000604482015260640162000966565b336000908152600d6020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152812054908190036200168c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4e6f7468696e6720746f20776974686472617700000000000000000000000000604482015260640162000966565b336000908152600e6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915290205442101562001728576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5769746864726177616c206e6f74207265616479000000000000000000000000604482015260640162000966565b336000908152600d6020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684528252808320839055600a90915281208054839290620017749084906200412f565b909155505073ffffffffffffffffffffffffffffffffffffffff82166000908152601460205260408120546402540be40090620017b29084620040d9565b620017be9190620040f3565b9050620017cc81836200412f565b600454909250620017f89073ffffffffffffffffffffffffffffffffffffffff858116911683620039af565b6200181b73ffffffffffffffffffffffffffffffffffffffff84163384620039af565b6040805183815260208101839052339173ffffffffffffffffffffffffffffffffffffffff8616917f2c827aaf63a2d33ada9256a258929e98957e25cc6b122c5d81fafa606249b3f291015b60405180910390a3505050565b6200187e620035ef565b73ffffffffffffffffffffffffffffffffffffffff8216620018fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f5a65726f41646472657373000000000000000000000000000000000000000000604482015260640162000966565b73ffffffffffffffffffffffffffffffffffffffff821660009081526002602052604090205460ff16156200198f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f416c72656164792077686974656c697374656400000000000000000000000000604482015260640162000966565b6200199c60018362003a8a565b73ffffffffffffffffffffffffffffffffffffffff808316600090815260126020526040902054168062001b095766038d7ea4c6800082101562001a3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f496e697469616c206465706f73697420746f6f20736d616c6c00000000000000604482015260640162000966565b8260405162001a4c9062003f63565b73ffffffffffffffffffffffffffffffffffffffff9091168152602001604051809103906000f08015801562001a86573d6000803e3d6000fd5b5073ffffffffffffffffffffffffffffffffffffffff848116600090815260126020908152604080832080547fffffffffffffffffffffffff000000000000000000000000000000000000000016948616949094179093556011905220670de0b6b3a76400009055905062001afd836001620010bb565b62001b09838362002446565b8073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3f67845b0831549d6cdea73c455caaeb3ddd0b14039c70f92cbd819cb956c7f60405160405180910390a3505050565b62000b2c81620007f4338462001c35565b62001b83620035ef565b62001b8f600062003b53565b565b73ffffffffffffffffffffffffffffffffffffffff80821660009081526012602090815260408083205481517f18160ddd0000000000000000000000000000000000000000000000000000000081529151939416926318160ddd926004808401939192918290030181865afa15801562001c0f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000b1a91906200415b565b73ffffffffffffffffffffffffffffffffffffffff8083166000908152600b6020908152604080832093851683529290529081205460ff161562001ccf5773ffffffffffffffffffffffffffffffffffffffff8216600090815260116020526040902054670de0b6b3a76400009062001caf85856200311b565b62001cbb9190620040d9565b62001cc79190620040f3565b905062000b1a565b5073ffffffffffffffffffffffffffffffffffffffff8083166000908152600c602090815260408083209385168352929052205462000b1a565b60085460ff1662001d77576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4561726c79207769746864726177616c2064697361626c656400000000000000604482015260640162000966565b73ffffffffffffffffffffffffffffffffffffffff821662001df6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f5a65726f41646472657373000000000000000000000000000000000000000000604482015260640162000966565b8060000362001e62576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e2030000000604482015260640162000966565b8062001e6f338462001c35565b101562001ed9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4e6f7420656e6f756768207374616b6564000000000000000000000000000000604482015260640162000966565b336000908152600d6020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091529020541562001f73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f5769746864726177616c20616c726561647920696e6974696174656400000000604482015260640162000966565b62001f7f338362003843565b336000908152600b6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915290205460ff1615620020a35773ffffffffffffffffffffffffffffffffffffffff821660009081526011602052604081205462001ff383670de0b6b3a7640000620040d9565b62001fff9190620040f3565b73ffffffffffffffffffffffffffffffffffffffff848116600090815260126020526040908190205490517f9dc29fac000000000000000000000000000000000000000000000000000000008152336004820152602481018490529293501690639dc29fac90604401600060405180830381600087803b1580156200208357600080fd5b505af115801562002098573d6000803e3d6000fd5b5050505050620021b6565b73ffffffffffffffffffffffffffffffffffffffff821660009081526009602052604081208054839290620020da9084906200412f565b9091555050336000908152600c6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915281208054839290620021219084906200412f565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600081815260106020908152604080832054338452600c835281842094845293909152902054670de0b6b3a7640000916200217891620040d9565b620021849190620040f3565b336000908152600f6020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091529020555b73ffffffffffffffffffffffffffffffffffffffff82166000908152601460205260408120546007546402540be40091620021f19162004145565b620021fd9084620040d9565b620022099190620040f3565b90506200221781836200412f565b600454909250620022439073ffffffffffffffffffffffffffffffffffffffff858116911683620039af565b6200226673ffffffffffffffffffffffffffffffffffffffff84163384620039af565b6040805183815260208101839052339173ffffffffffffffffffffffffffffffffffffffff8616917f293037788d87ac1cd6e14a58daea87cdc73495ac74b7be45eabf2ea86d256697910162001867565b620022c1620035ef565b64012a05f20081111562002332576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f46656520746f6f20686967680000000000000000000000000000000000000000604482015260640162000966565b73ffffffffffffffffffffffffffffffffffffffff8216600081815260146020908152604091829020849055815192835282018390527f6c8b1187e7b5f6818a7d98d4aa5cb3a6efdd96a57f2e3cbd5da405dfd1a91997910160405180910390a15050565b620023a1620035ef565b62278d0081111562002410576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f5769746864726177616c20706572696f6420746f6f206c6f6e67000000000000604482015260640162000966565b60058190556040518181527f4157b30b99fc9ed1b54c707f60552f93b22a74b0859af295ae63994b387006ee9060200162000f96565b73ffffffffffffffffffffffffffffffffffffffff8216620024c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f5a65726f41646472657373000000000000000000000000000000000000000000604482015260640162000966565b8060000362002531576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f5a65726f416d6f756e7400000000000000000000000000000000000000000000604482015260640162000966565b73ffffffffffffffffffffffffffffffffffffffff821660009081526002602052604090205460ff16620025c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4173736574206e6f7420616c6c6f776564000000000000000000000000000000604482015260640162000966565b600060065460001462002602576402540be40060065483620025e59190620040d9565b620025f19190620040f3565b9050620025ff81836200412f565b91505b73ffffffffffffffffffffffffffffffffffffffff8316600090815260136020908152604080832054600a909252909120548390620026418662001051565b6200264d919062004145565b62002659919062004145565b1115620026c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4465706f73697420636170206578636565646564000000000000000000000000604482015260640162000966565b620026cf338462003843565b620027013330620026e1848662004145565b73ffffffffffffffffffffffffffffffffffffffff871692919062003bc8565b6004546200272a9073ffffffffffffffffffffffffffffffffffffffff858116911683620039af565b336000908152600b6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915290205460ff16156200284e5773ffffffffffffffffffffffffffffffffffffffff83166000908152601160205260408120546200279e84670de0b6b3a7640000620040d9565b620027aa9190620040f3565b73ffffffffffffffffffffffffffffffffffffffff858116600090815260126020526040908190205490517f40c10f190000000000000000000000000000000000000000000000000000000081523360048201526024810184905292935016906340c10f1990604401600060405180830381600087803b1580156200282e57600080fd5b505af115801562002843573d6000803e3d6000fd5b505050505062002961565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260096020526040812080548492906200288590849062004145565b9091555050336000908152600c6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281208054849290620028cc90849062004145565b909155505073ffffffffffffffffffffffffffffffffffffffff8316600081815260106020908152604080832054338452600c835281842094845293909152902054670de0b6b3a7640000916200292391620040d9565b6200292f9190620040f3565b336000908152600f6020908152604080832073ffffffffffffffffffffffffffffffffffffffff881684529091529020555b6040805183815260208101839052339173ffffffffffffffffffffffffffffffffffffffff8616917f6c86f3fd5118b3aa8bb4f389a617046de0a3d3d477de1a1673d227f802f616dc910162001867565b620029bc620035ef565b639502f90081111562002a2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f46656520746f6f20686967680000000000000000000000000000000000000000604482015260640162000966565b60078190556040518181527f864cabeb83698b194f9b49e7f58558d83cd8e635575ba53f511f37c834ece71c9060200162000f96565b73ffffffffffffffffffffffffffffffffffffffff821662002ae1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f5a65726f41646472657373000000000000000000000000000000000000000000604482015260640162000966565b8060000362002b4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e2030000000604482015260640162000966565b8062002b5a338462001c35565b101562002bc4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4e6f7420656e6f756768207374616b6564000000000000000000000000000000604482015260640162000966565b62002bd0338362003843565b336000908152600b6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915290205460ff161562002cf45773ffffffffffffffffffffffffffffffffffffffff821660009081526011602052604081205462002c4483670de0b6b3a7640000620040d9565b62002c509190620040f3565b73ffffffffffffffffffffffffffffffffffffffff848116600090815260126020526040908190205490517f9dc29fac000000000000000000000000000000000000000000000000000000008152336004820152602481018490529293501690639dc29fac90604401600060405180830381600087803b15801562002cd457600080fd5b505af115801562002ce9573d6000803e3d6000fd5b505050505062002e07565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600960205260408120805483929062002d2b9084906200412f565b9091555050336000908152600c6020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091528120805483929062002d729084906200412f565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600081815260106020908152604080832054338452600c835281842094845293909152902054670de0b6b3a76400009162002dc991620040d9565b62002dd59190620040f3565b336000908152600f6020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091529020555b336000908152600d6020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091528120805483929062002e4990849062004145565b909155505073ffffffffffffffffffffffffffffffffffffffff82166000908152600a60205260408120805483929062002e8590849062004145565b909155505060055462002e99904262004145565b336000818152600e6020908152604080832073ffffffffffffffffffffffffffffffffffffffff881680855290835292819020859055805186815291820194909452919290917f2e16c360bf25f9193c8e78b0fcdf02bacfd34fd98ec9fe4aa2549e15346dafd2910160405180910390a360055460000362002f205762002f208262001570565b5050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526002602052604081205460ff1662000b1a565b62002f5d620035ef565b73ffffffffffffffffffffffffffffffffffffffff811662002fdc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f5a65726f41646472657373000000000000000000000000000000000000000000604482015260640162000966565b600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d19060200162000f96565b6200305a620035ef565b73ffffffffffffffffffffffffffffffffffffffff8116620030ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840162000966565b62000b2c8162003b53565b62000b2c8162000703338462001c35565b73ffffffffffffffffffffffffffffffffffffffff8181166000908152601260205260408082205490517f70a082310000000000000000000000000000000000000000000000000000000081528584166004820152919216906370a0823190602401602060405180830381865afa1580156200319b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000b1791906200415b565b620031cb620035ef565b73ffffffffffffffffffffffffffffffffffffffff82166200324a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f5a65726f41646472657373000000000000000000000000000000000000000000604482015260640162000966565b73ffffffffffffffffffffffffffffffffffffffff821660008181526013602052604090819020839055517fdb0e031f017e9837f619ff44f6ce88716d74b5a62af3de735b952fb47887d96590620032a59084815260200190565b60405180910390a25050565b73ffffffffffffffffffffffffffffffffffffffff821662003330576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f5a65726f41646472657373000000000000000000000000000000000000000000604482015260640162000966565b73ffffffffffffffffffffffffffffffffffffffff821660009081526002602052604090205460ff1615806200336e57506200336c8262001051565b155b8062003378575080155b1562003382575050565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201523060248201526044810182905273ffffffffffffffffffffffffffffffffffffffff8316906323b872dd906064016020604051808303816000875af192505050801562003438575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252620034359181019062004175565b60015b62003441575050565b5060006200344f8362001051565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260096020526040902054620034819084620040d9565b6200348d9190620040f3565b905060006200349d82846200412f565b90508115620035295773ffffffffffffffffffffffffffffffffffffffff8416600090815260096020526040902054620034e083670de0b6b3a7640000620040d9565b620034ec9190620040f3565b73ffffffffffffffffffffffffffffffffffffffff8516600090815260106020526040812080549091906200352390849062004145565b90915550505b801562003598576200353b8462001b91565b6200354f82670de0b6b3a7640000620040d9565b6200355b9190620040f3565b73ffffffffffffffffffffffffffffffffffffffff8516600090815260116020526040812080549091906200359290849062004145565b90915550505b8373ffffffffffffffffffffffffffffffffffffffff167fea310f979febc9b4af7c2bc0ae7bf01599119a08a90d4200cd0e2548fcf601c984604051620035e191815260200190565b60405180910390a250505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331462001b8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000966565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604090205460ff161562002f205773ffffffffffffffffffffffffffffffffffffffff8116600090815260018084016020908152604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905560028601909152822054845490929185916200371191906200412f565b8154811062003724576200372462004195565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff90811680845260028801909252604080842086905590861683528220919091558454909150819085908490811062003783576200378362004195565b600091825260209091200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790558354849080620037e557620037e5620041c4565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550505050565b73ffffffffffffffffffffffffffffffffffffffff8116620038c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f5a65726f41646472657373000000000000000000000000000000000000000000604482015260640162000966565b6000620038d0838362000a51565b905080600003620038e057505050565b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600f60209081526040808320938616835292905290812080548392906200392690849062004145565b909155506200394f905073ffffffffffffffffffffffffffffffffffffffff83168483620039af565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fd5c7f00f812b57a4de7d2be4d224a696e313e9a810ff86cdeb6caf3ac9d0d266836040516200186791815260200190565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905262003a859084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915262003c2e565b505050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604090205460ff1662002f205773ffffffffffffffffffffffffffffffffffffffff16600081815260018381016020908152604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016841790558554600287018352908420819055918201855593825292902090910180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169091179055565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905262003c289085907f23b872dd000000000000000000000000000000000000000000000000000000009060840162003a02565b50505050565b600062003c92826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1662003d419092919063ffffffff16565b80519091501562003a85578080602001905181019062003cb3919062004175565b62003a85576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840162000966565b606062003d52848460008562003d5a565b949350505050565b60608247101562003dee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840162000966565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405162003e19919062004219565b60006040518083038185875af1925050503d806000811462003e58576040519150601f19603f3d011682016040523d82523d6000602084013e62003e5d565b606091505b509150915062003e708783838762003e7b565b979650505050505050565b6060831562003f1657825160000362003f0e5773ffffffffffffffffffffffffffffffffffffffff85163b62003f0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000966565b508162003d52565b62003d52838381511562003f2d5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000966919062004237565b6114cd806200428b83390190565b803573ffffffffffffffffffffffffffffffffffffffff8116811462003f9657600080fd5b919050565b60006020828403121562003fae57600080fd5b62000b178262003f71565b6000806040838503121562003fcd57600080fd5b62003fd88362003f71565b915062003fe86020840162003f71565b90509250929050565b801515811462000b2c57600080fd5b6000602082840312156200401357600080fd5b8135620040208162003ff1565b9392505050565b6000602082840312156200403a57600080fd5b5035919050565b600080604083850312156200405557600080fd5b620040608362003f71565b91506020830135620040728162003ff1565b809150509250929050565b600080604083850312156200409157600080fd5b6200409c8362003f71565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141762000b1a5762000b1a620040aa565b6000826200412a577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b8181038181111562000b1a5762000b1a620040aa565b8082018082111562000b1a5762000b1a620040aa565b6000602082840312156200416e57600080fd5b5051919050565b6000602082840312156200418857600080fd5b8151620040208162003ff1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60005b8381101562004210578181015183820152602001620041f6565b50506000910152565b600082516200422d818460208701620041f3565b9190910192915050565b602081526000825180602084015262004258816040850160208701620041f3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe60c06040523480156200001157600080fd5b50604051620014cd380380620014cd8339810160408190526200003491620001c8565b806001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa15801562000073573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200009d919081019062000236565b604051602001620000af9190620002ee565b604051602081830303815290604052816001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620000fd573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000127919081019062000236565b60405160200162000139919062000328565b60408051601f198184030181529190526003620001578382620003e5565b506004620001668282620003e5565b5050506001600160a01b038116620001b25760405162461bcd60e51b815260206004820152600b60248201526a5a65726f4164647265737360a81b604482015260640160405180910390fd5b6001600160a01b03166080523360a052620004b1565b600060208284031215620001db57600080fd5b81516001600160a01b0381168114620001f357600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b60005b838110156200022d57818101518382015260200162000213565b50506000910152565b6000602082840312156200024957600080fd5b81516001600160401b03808211156200026157600080fd5b818401915084601f8301126200027657600080fd5b8151818111156200028b576200028b620001fa565b604051601f8201601f19908116603f01168101908382118183101715620002b657620002b6620001fa565b81604052828152876020848701011115620002d057600080fd5b620002e383602083016020880162000210565b979650505050505050565b6f020baba37b1b7b6b837bab73234b733960851b8152600082516200031b81601085016020870162000210565b9190910160100192915050565b636175746f60e01b8152600082516200034981600485016020870162000210565b9190910160040192915050565b600181811c908216806200036b57607f821691505b6020821081036200038c57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620003e057600081815260208120601f850160051c81016020861015620003bb5750805b601f850160051c820191505b81811015620003dc57828155600101620003c7565b5050505b505050565b81516001600160401b03811115620004015762000401620001fa565b620004198162000412845462000356565b8462000392565b602080601f831160018114620004515760008415620004385750858301515b600019600386901b1c1916600185901b178555620003dc565b600085815260208120601f198616915b82811015620004825788860151825594840194600190910190840162000461565b5085821015620004a15787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a051610fe8620004e56000396000818161025f015281816103fb01526104bc0152600061019c0152610fe86000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80636f307dc311610097578063a457c2d711610066578063a457c2d714610234578063a9059cbb14610247578063c45a01551461025a578063dd62ed3e1461028157600080fd5b80636f307dc31461019757806370a08231146101e357806395d89b41146102195780639dc29fac1461022157600080fd5b806323b872dd116100d357806323b872dd1461014d578063313ce56714610160578063395093511461016f57806340c10f191461018257600080fd5b806306fdde03146100fa578063095ea7b31461011857806318160ddd1461013b575b600080fd5b6101026102c7565b60405161010f9190610dd5565b60405180910390f35b61012b610126366004610e6a565b610359565b604051901515815260200161010f565b6002545b60405190815260200161010f565b61012b61015b366004610e94565b610373565b6040516012815260200161010f565b61012b61017d366004610e6a565b610397565b610195610190366004610e6a565b6103e3565b005b6101be7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161010f565b61013f6101f1366004610ed0565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b610102610495565b61019561022f366004610e6a565b6104a4565b61012b610242366004610e6a565b61054d565b61012b610255366004610e6a565b61061e565b6101be7f000000000000000000000000000000000000000000000000000000000000000081565b61013f61028f366004610ef2565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6060600380546102d690610f25565b80601f016020809104026020016040519081016040528092919081815260200182805461030290610f25565b801561034f5780601f106103245761010080835404028352916020019161034f565b820191906000526020600020905b81548152906001019060200180831161033257829003601f168201915b5050505050905090565b60003361036781858561062c565b60019150505b92915050565b6000336103818582856107e0565b61038c8585856108b7565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919061036790829086906103de908790610f78565b61062c565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610487576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4f6e6c7920666163746f7279000000000000000000000000000000000000000060448201526064015b60405180910390fd5b6104918282610b26565b5050565b6060600480546102d690610f25565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610543576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4f6e6c7920666163746f72790000000000000000000000000000000000000000604482015260640161047e565b6104918282610c19565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015610611576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f000000000000000000000000000000000000000000000000000000606482015260840161047e565b61038c828686840361062c565b6000336103678185856108b7565b73ffffffffffffffffffffffffffffffffffffffff83166106ce576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015260840161047e565b73ffffffffffffffffffffffffffffffffffffffff8216610771576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015260840161047e565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146108b157818110156108a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161047e565b6108b1848484840361062c565b50505050565b73ffffffffffffffffffffffffffffffffffffffff831661095a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f6472657373000000000000000000000000000000000000000000000000000000606482015260840161047e565b73ffffffffffffffffffffffffffffffffffffffff82166109fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015260840161047e565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610ab3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e63650000000000000000000000000000000000000000000000000000606482015260840161047e565b73ffffffffffffffffffffffffffffffffffffffff848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a36108b1565b73ffffffffffffffffffffffffffffffffffffffff8216610ba3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161047e565b8060026000828254610bb59190610f78565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8216610cbc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f7300000000000000000000000000000000000000000000000000000000000000606482015260840161047e565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015610d72576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f6365000000000000000000000000000000000000000000000000000000000000606482015260840161047e565b73ffffffffffffffffffffffffffffffffffffffff83166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91016107d3565b600060208083528351808285015260005b81811015610e0257858101830151858201604001528201610de6565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610e6557600080fd5b919050565b60008060408385031215610e7d57600080fd5b610e8683610e41565b946020939093013593505050565b600080600060608486031215610ea957600080fd5b610eb284610e41565b9250610ec060208501610e41565b9150604084013590509250925092565b600060208284031215610ee257600080fd5b610eeb82610e41565b9392505050565b60008060408385031215610f0557600080fd5b610f0e83610e41565b9150610f1c60208401610e41565b90509250929050565b600181811c90821680610f3957607f821691505b602082108103610f72577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b8082018082111561036d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fdfea2646970667358221220ce939e86e4dcfc9caa55fda8d25443a6063624b778e98902bc48352e294f37b464736f6c63430008130033a264697066735822122072436d745565bbb533e0b7b74755ff3cf4916f91ecbe6004126344cb06ac618d64736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000f416c2b41fb6c592c9ba7cb6b2f985ed593a51d7
-----Decoded View---------------
Arg [0] : _treasury (address): 0xF416C2b41Fb6c592c9BA7cB6B2f985ed593A51d7
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000f416c2b41fb6c592c9ba7cb6b2f985ed593a51d7
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 ]
[ 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.