ERC-20
Overview
Max Total Supply
25,721,152.06 gSTFX
Holders
94
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 18 Decimals)
Balance
49,999.98 gSTFXValue
$0.00Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
Stake
Compiler Version
v0.8.19+commit.7dd6d404
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.17; import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; error NotOwner(); error BalanceLessThanAmount(); error StakingPeriodMismatch(); error ZeroAmount(); error ZeroAddress(); error StakingIdMismatch(); error StakeNotMature(); error StakeAlreadyMature(); error AlreadyClaimed(); error LengthMismatch(); error NonTransferable(); error StakeCompleted(); error NoRewardsToClaim(); contract Stake is ERC20 { /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event OwnerUpdate(address indexed owner); event Withdraw(address indexed tokenAddress, uint256 balance); event AddInterestRate(uint8 period, uint96 rate); event AddgStfxMultiplier(uint8 period, uint32 multiplier); event UpdateBurnPercent(uint32 percent); event UpdateBurnAddress(address indexed burnAddress); event AddStake( address indexed staker, uint256 stakeNumber, uint96 amount, uint96 expiryAmount, uint40 expiryTime, uint8 period ); event Unstake(address indexed staker, uint256[] stakeNumber, uint96 totalTransferAmount, uint96 totalBurnAmount); event Claim( address indexed staker, uint256[] stakeNumber, uint96 amount, uint96 expiryAmount, uint96 transferAmount ); event ClaimRewards(address indexed staker, uint256[] stakeNumber, uint96 totalRewards); /*////////////////////////////////////////////////////////////// STATE //////////////////////////////////////////////////////////////*/ struct StakingInfo { StakingPeriod period; uint40 startTime; uint40 expiryTime; uint96 amount; uint96 expiryAmount; uint96 claimedAmount; uint96 gStfxAmount; bool isCompleted; } enum StakingPeriod { MONTH, // 1 months - 30 days QUARTER, // 3 months - 90 days HALF, // 6 months - 180 days YEAR, // 1 year - 365 days TWO_YEAR // 2 years - 730 days } address public owner; address public token; uint32 public burnPercent; address public burnAddress; uint96 public totalStaked; uint96 public burntToDate; uint96 public rewardsToDate; mapping(address => StakingInfo[]) public stakingInfo; mapping(uint8 => uint96) public interestRate; mapping(uint8 => uint32) public gStfxMultiplier; /*////////////////////////////////////////////////////////////// CONSTRUCTOR/MODIFIERS //////////////////////////////////////////////////////////////*/ constructor(address _token) ERC20("gSTFX", "gSTFX") { owner = msg.sender; token = _token; burnPercent = 20000; // 20% burnAddress = address(0x000000000000000000000000000000000000dEaD); } modifier onlyOwner() { if (msg.sender != owner) revert NotOwner(); _; } /*////////////////////////////////////////////////////////////// VIEW //////////////////////////////////////////////////////////////*/ function getNumberOfStakes(address staker) public view returns (uint256) { return stakingInfo[staker].length; } function getAllStakes(address staker) public view returns (StakingInfo[] memory) { uint256 length = stakingInfo[staker].length; StakingInfo[] memory allStakes = new StakingInfo[](length); for (uint256 i = 0; i < length;) { allStakes[i] = stakingInfo[staker][i]; unchecked { ++i; } } return allStakes; } function getStakingInfo(address staker, uint256 n) public view returns (StakingInfo memory) { return stakingInfo[staker][n]; } function getIsStakeMature(address staker, uint256 n) public view returns (bool isMature) { if (block.timestamp >= stakingInfo[staker][n].expiryTime) isMature = true; } function getStakeAmount(address staker, uint256[] memory n) public view returns (uint96 amount) { if (n.length > getNumberOfStakes(staker)) revert LengthMismatch(); for (uint256 i = 0; i < n.length;) { StakingInfo memory s = stakingInfo[staker][n[i]]; amount += s.amount; unchecked { ++i; } } } function getExpiryAmount(address staker, uint256[] memory n) public view returns (uint96 expiryAmount) { if (n.length > getNumberOfStakes(staker)) revert LengthMismatch(); for (uint256 i = 0; i < n.length;) { StakingInfo memory s = stakingInfo[staker][n[i]]; expiryAmount += s.expiryAmount; unchecked { ++i; } } } function getClaimedAmount(address staker, uint256[] memory n) public view returns (uint96 claimedAmount) { if (n.length > getNumberOfStakes(staker)) revert LengthMismatch(); for (uint256 i = 0; i < n.length;) { StakingInfo memory s = stakingInfo[staker][n[i]]; claimedAmount += s.claimedAmount; unchecked { ++i; } } } function getAccruedRewards(address staker, uint256[] memory n) public view returns (uint96 claimableAmount) { if (n.length > getNumberOfStakes(staker)) revert LengthMismatch(); for (uint256 i = 0; i < n.length;) { StakingInfo memory s = stakingInfo[staker][n[i]]; if (s.isCompleted) { claimableAmount += 0; } else { if (block.timestamp >= s.expiryTime) { claimableAmount += uint96(s.expiryAmount - s.amount); } else { claimableAmount += uint96( ((s.expiryAmount - s.amount) * (block.timestamp - s.startTime)) / (s.expiryTime - s.startTime) ); } } unchecked { ++i; } } } function getBurnAmount(address staker, uint256[] memory n) public view returns (uint96 burnAmount) { if (n.length > getNumberOfStakes(staker)) revert LengthMismatch(); for (uint256 i = 0; i < n.length;) { StakingInfo memory s = stakingInfo[staker][n[i]]; if ((block.timestamp >= s.expiryTime) || s.isCompleted) { burnAmount += 0; } else { burnAmount += uint96( (uint256(burnPercent) * s.amount * (s.expiryTime - block.timestamp)) / (uint256(s.expiryTime - s.startTime) * 100000) ); } unchecked { ++i; } } } function getAccruedRewardsPerStake(address staker, uint256 n) public view returns (uint96 claimableAmount) { StakingInfo memory s = stakingInfo[staker][n]; if (s.isCompleted) { claimableAmount = 0; } else { if (block.timestamp >= s.expiryTime) { claimableAmount = uint96(s.expiryAmount - s.amount); } else { claimableAmount = uint96( ((s.expiryAmount - s.amount) * (block.timestamp - s.startTime)) / (s.expiryTime - s.startTime) ); } } } function getBurnAmountPerStake(address staker, uint256 n) public view returns (uint96 burnAmount) { StakingInfo memory s = stakingInfo[staker][n]; if ((block.timestamp >= s.expiryTime) || s.isCompleted) { burnAmount = 0; } else { burnAmount = uint96( (uint256(burnPercent) * s.amount * (s.expiryTime - block.timestamp)) / (uint256(s.expiryTime - s.startTime) * 100000) ); } } function getStats() public view returns (uint96, uint96, uint96) { return (totalStaked, rewardsToDate, burntToDate); } function getStatsPerStaker(address staker) public view returns (uint96 amount, uint96 expiryAmount, uint96 claimedAmount, uint96 accruedRewards) { uint256 length = getNumberOfStakes(staker); for (uint256 i = 0; i < length;) { StakingInfo memory s = stakingInfo[staker][i]; amount += s.amount; expiryAmount += s.expiryAmount; claimedAmount += s.claimedAmount; accruedRewards += getAccruedRewardsPerStake(staker, i); unchecked { ++i; } } } function getIdsForClaimRewards(address staker) public view returns (uint256[] memory n) { uint256 length = getNumberOfStakes(staker); for (uint256 i = 0; i < length;) { StakingInfo memory s = stakingInfo[staker][i]; if (!s.isCompleted && (block.timestamp < s.expiryTime)) { assembly { let currentLength := mload(n) mstore(n, add(currentLength, 1)) mstore(add(n, mul(add(currentLength, 1), 32)), i) } } unchecked { ++i; } } } /*////////////////////////////////////////////////////////////// SETTERS //////////////////////////////////////////////////////////////*/ function setOwner(address newOwner) external onlyOwner { if (newOwner == address(0)) revert ZeroAddress(); owner = newOwner; emit OwnerUpdate(newOwner); } function addInterestRate(StakingPeriod period, uint96 rate) external onlyOwner { if (rate < 1) revert ZeroAmount(); interestRate[uint8(period)] = rate; emit AddInterestRate(uint8(period), rate); } function addgStfxMultiplier(StakingPeriod period, uint32 multiplier) external onlyOwner { if (multiplier < 1) revert ZeroAmount(); gStfxMultiplier[uint8(period)] = multiplier; emit AddgStfxMultiplier(uint8(period), multiplier); } function updateBurnPercent(uint32 percent) external onlyOwner { if (percent < 1) revert ZeroAmount(); burnPercent = percent; emit UpdateBurnPercent(percent); } function updateBurnAddress(address burn) external onlyOwner { burnAddress = burn; emit UpdateBurnAddress(burn); } /*////////////////////////////////////////////////////////////// INTERNAL //////////////////////////////////////////////////////////////*/ function _setStakingPeriod(StakingPeriod period) internal view returns (uint40 expiryTime) { if (period == StakingPeriod.MONTH) { expiryTime = uint40(block.timestamp + 30 days); } else if (period == StakingPeriod.QUARTER) { expiryTime = uint40(block.timestamp + 90 days); } else if (period == StakingPeriod.HALF) { expiryTime = uint40(block.timestamp + 180 days); } else if (period == StakingPeriod.YEAR) { expiryTime = uint40(block.timestamp + 365 days); } else if (period == StakingPeriod.TWO_YEAR) { expiryTime = uint40(block.timestamp + 730 days); } else { revert StakingPeriodMismatch(); } } function _stake(uint96 amount, StakingPeriod period) internal view returns (StakingInfo memory s) { s.startTime = uint40(block.timestamp); s.amount = amount; s.expiryAmount = uint96(((uint256(amount) * uint256(interestRate[uint8(period)])) / 100e18) + uint256(amount)); s.period = period; s.expiryTime = _setStakingPeriod(period); s.gStfxAmount = uint96((uint256(gStfxMultiplier[uint8(period)]) * uint256(s.amount)) / 1000); } /*////////////////////////////////////////////////////////////// EXTERNAL //////////////////////////////////////////////////////////////*/ /// @notice add a stake with the input amount for the address calling this function /// @dev approve has to be called before calling this function /// @param amount the amount of tokens the staker wants to stake /// @param period the time period from the enum function stake(uint96 amount, StakingPeriod period) external { if (IERC20(token).balanceOf(msg.sender) < amount) revert BalanceLessThanAmount(); if (interestRate[uint8(period)] == 0) revert StakingPeriodMismatch(); StakingInfo memory s = _stake(amount, period); stakingInfo[msg.sender].push(s); totalStaked += amount; uint256 length = stakingInfo[msg.sender].length; _mint(msg.sender, s.gStfxAmount); IERC20(token).transferFrom(msg.sender, address(this), amount); emit AddStake(msg.sender, length - 1, amount, s.expiryAmount, s.expiryTime, uint8(period)); } /// @notice restakes the initial amount with the rewards accrued till now and restakes it for the new time period /// @dev the new period has to be more than the existing stake period /// @param n the id of the stake /// @param period the new period of the stake which can only be more than the existing stake function restake(uint256 n, StakingPeriod period) external { uint256 length = getNumberOfStakes(msg.sender); if (n >= length) revert StakingIdMismatch(); StakingInfo memory s = getStakingInfo(msg.sender, n); if (block.timestamp >= s.expiryTime) revert StakeAlreadyMature(); if (uint8(period) < uint8(s.period)) revert StakingPeriodMismatch(); uint96 stakedRewardTillNow = getAccruedRewardsPerStake(msg.sender, n); StakingInfo memory sAfterRestake = _stake(s.amount + (stakedRewardTillNow - s.claimedAmount), period); stakingInfo[msg.sender][n] = sAfterRestake; totalStaked += stakedRewardTillNow - s.claimedAmount; _mint(msg.sender, sAfterRestake.gStfxAmount - s.gStfxAmount); emit AddStake( msg.sender, n, sAfterRestake.amount, sAfterRestake.expiryAmount, sAfterRestake.expiryTime, uint8(sAfterRestake.period) ); } /// @notice unstakes prematurely and transfers `amount + rewards - burnAmount` to the staker /// @dev burns `burnPercent` of the remaining amount of stake /// @param n array of all the staking ids function unstake(uint256[] memory n) external { uint256 length = getNumberOfStakes(msg.sender); if (n.length > length) revert LengthMismatch(); uint96 totalRewards; uint96 totalTransferAmount; uint96 totalBurnAmount; uint96 gStfxToBurn; for (uint256 i = 0; i < n.length;) { if (n[i] >= length) revert StakingIdMismatch(); StakingInfo memory s = getStakingInfo(msg.sender, n[i]); if (block.timestamp >= s.expiryTime) revert StakeAlreadyMature(); if (s.isCompleted) revert StakeCompleted(); uint96 accruedRewards = getAccruedRewardsPerStake(msg.sender, n[i]); uint96 burnAmount = getBurnAmountPerStake(msg.sender, n[i]); totalRewards += accruedRewards - s.claimedAmount; totalTransferAmount += (s.amount - burnAmount) + (accruedRewards - s.claimedAmount); totalBurnAmount += burnAmount; gStfxToBurn += s.gStfxAmount; stakingInfo[msg.sender][n[i]].claimedAmount = accruedRewards; stakingInfo[msg.sender][n[i]].isCompleted = true; unchecked { ++i; } } rewardsToDate += totalRewards; burntToDate += totalBurnAmount; _burn(msg.sender, gStfxToBurn); IERC20(token).transfer(msg.sender, totalTransferAmount); IERC20(token).transfer(burnAddress, totalBurnAmount); emit Unstake(msg.sender, n, totalTransferAmount, totalBurnAmount); } /// @notice transfers the initial amount with the remaining rewards after the stake matures to the staker /// @dev can be called after all the stakes in the array are matured /// @param n array of the staking ids function claim(uint256[] memory n) external { uint96 totalStakeAmount; uint96 totalExpiryAmount; uint96 transferAmount; uint96 gStfxToBurn; uint96 totalRewardsToDate; uint256 length = getNumberOfStakes(msg.sender); if (n.length > length) revert LengthMismatch(); for (uint256 i = 0; i < n.length;) { if (n[i] >= length) revert StakingIdMismatch(); StakingInfo memory s = getStakingInfo(msg.sender, n[i]); if (block.timestamp < s.expiryTime) revert StakeNotMature(); if (s.isCompleted) revert StakeCompleted(); totalStakeAmount += s.amount; totalExpiryAmount += s.expiryAmount; transferAmount += s.expiryAmount - s.claimedAmount; totalRewardsToDate += s.expiryAmount - s.amount - s.claimedAmount; gStfxToBurn += s.gStfxAmount; stakingInfo[msg.sender][n[i]].claimedAmount = s.expiryAmount - s.amount; stakingInfo[msg.sender][n[i]].isCompleted = true; unchecked { ++i; } } rewardsToDate += totalRewardsToDate; _burn(msg.sender, gStfxToBurn); IERC20(token).transfer(msg.sender, transferAmount); emit Claim(msg.sender, n, totalStakeAmount, totalExpiryAmount, transferAmount); } /// @notice transfers all the eligible rewards of all the stakes in the array to the staker /// @param n array of the staking ids function claimRewards(uint256[] memory n) external { uint256 length = getNumberOfStakes(msg.sender); if (n.length > length) revert LengthMismatch(); uint96 transferAmount; for (uint256 i = 0; i < n.length;) { if (n[i] >= length) revert StakingIdMismatch(); StakingInfo memory s = getStakingInfo(msg.sender, n[i]); uint96 claimableAmount = getAccruedRewardsPerStake(msg.sender, n[i]); if ((s.claimedAmount < claimableAmount) && !s.isCompleted) { uint96 claimedAmountTillNow = s.claimedAmount; transferAmount += claimableAmount - claimedAmountTillNow; stakingInfo[msg.sender][n[i]].claimedAmount = claimableAmount; } unchecked { ++i; } } if (transferAmount == 0) revert NoRewardsToClaim(); rewardsToDate += transferAmount; IERC20(token).transfer(msg.sender, transferAmount); emit ClaimRewards(msg.sender, n, transferAmount); } function withdraw(address tokenAddress) external onlyOwner { uint256 balance = IERC20(tokenAddress).balanceOf(address(this)); IERC20(tokenAddress).transfer(owner, balance); emit Withdraw(tokenAddress, balance); } /*////////////////////////////////////////////////////////////// ERC20 //////////////////////////////////////////////////////////////*/ function approve(address, uint256) public virtual override returns (bool) { revert NonTransferable(); } function transfer(address, uint256) public virtual override returns (bool) { revert NonTransferable(); } function transferFrom(address, address, uint256) public virtual override returns (bool) { revert NonTransferable(); } }
// 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 (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 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 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; } }
{ "remappings": [ "@openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/", "@openzeppelin/=lib/openzeppelin-contracts/", "@synthetix/=src/interfaces/synthetix/", "ds-test/=lib/forge-std/lib/ds-test/src/", "forge-std/=lib/forge-std/src/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "solmate/=lib/solmate/src/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "paris", "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"BalanceLessThanAmount","type":"error"},{"inputs":[],"name":"LengthMismatch","type":"error"},{"inputs":[],"name":"NoRewardsToClaim","type":"error"},{"inputs":[],"name":"NonTransferable","type":"error"},{"inputs":[],"name":"NotOwner","type":"error"},{"inputs":[],"name":"StakeAlreadyMature","type":"error"},{"inputs":[],"name":"StakeCompleted","type":"error"},{"inputs":[],"name":"StakeNotMature","type":"error"},{"inputs":[],"name":"StakingIdMismatch","type":"error"},{"inputs":[],"name":"StakingPeriodMismatch","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"inputs":[],"name":"ZeroAmount","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"period","type":"uint8"},{"indexed":false,"internalType":"uint96","name":"rate","type":"uint96"}],"name":"AddInterestRate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"stakeNumber","type":"uint256"},{"indexed":false,"internalType":"uint96","name":"amount","type":"uint96"},{"indexed":false,"internalType":"uint96","name":"expiryAmount","type":"uint96"},{"indexed":false,"internalType":"uint40","name":"expiryTime","type":"uint40"},{"indexed":false,"internalType":"uint8","name":"period","type":"uint8"}],"name":"AddStake","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"period","type":"uint8"},{"indexed":false,"internalType":"uint32","name":"multiplier","type":"uint32"}],"name":"AddgStfxMultiplier","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"stakeNumber","type":"uint256[]"},{"indexed":false,"internalType":"uint96","name":"amount","type":"uint96"},{"indexed":false,"internalType":"uint96","name":"expiryAmount","type":"uint96"},{"indexed":false,"internalType":"uint96","name":"transferAmount","type":"uint96"}],"name":"Claim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"stakeNumber","type":"uint256[]"},{"indexed":false,"internalType":"uint96","name":"totalRewards","type":"uint96"}],"name":"ClaimRewards","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"}],"name":"OwnerUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"stakeNumber","type":"uint256[]"},{"indexed":false,"internalType":"uint96","name":"totalTransferAmount","type":"uint96"},{"indexed":false,"internalType":"uint96","name":"totalBurnAmount","type":"uint96"}],"name":"Unstake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"burnAddress","type":"address"}],"name":"UpdateBurnAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"percent","type":"uint32"}],"name":"UpdateBurnPercent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"balance","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[{"internalType":"enum Stake.StakingPeriod","name":"period","type":"uint8"},{"internalType":"uint96","name":"rate","type":"uint96"}],"name":"addInterestRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum Stake.StakingPeriod","name":"period","type":"uint8"},{"internalType":"uint32","name":"multiplier","type":"uint32"}],"name":"addgStfxMultiplier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"burnAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"burnPercent","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"burntToDate","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"n","type":"uint256[]"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"n","type":"uint256[]"}],"name":"claimRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"","type":"uint8"}],"name":"gStfxMultiplier","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"staker","type":"address"},{"internalType":"uint256[]","name":"n","type":"uint256[]"}],"name":"getAccruedRewards","outputs":[{"internalType":"uint96","name":"claimableAmount","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"staker","type":"address"},{"internalType":"uint256","name":"n","type":"uint256"}],"name":"getAccruedRewardsPerStake","outputs":[{"internalType":"uint96","name":"claimableAmount","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"staker","type":"address"}],"name":"getAllStakes","outputs":[{"components":[{"internalType":"enum Stake.StakingPeriod","name":"period","type":"uint8"},{"internalType":"uint40","name":"startTime","type":"uint40"},{"internalType":"uint40","name":"expiryTime","type":"uint40"},{"internalType":"uint96","name":"amount","type":"uint96"},{"internalType":"uint96","name":"expiryAmount","type":"uint96"},{"internalType":"uint96","name":"claimedAmount","type":"uint96"},{"internalType":"uint96","name":"gStfxAmount","type":"uint96"},{"internalType":"bool","name":"isCompleted","type":"bool"}],"internalType":"struct Stake.StakingInfo[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"staker","type":"address"},{"internalType":"uint256[]","name":"n","type":"uint256[]"}],"name":"getBurnAmount","outputs":[{"internalType":"uint96","name":"burnAmount","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"staker","type":"address"},{"internalType":"uint256","name":"n","type":"uint256"}],"name":"getBurnAmountPerStake","outputs":[{"internalType":"uint96","name":"burnAmount","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"staker","type":"address"},{"internalType":"uint256[]","name":"n","type":"uint256[]"}],"name":"getClaimedAmount","outputs":[{"internalType":"uint96","name":"claimedAmount","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"staker","type":"address"},{"internalType":"uint256[]","name":"n","type":"uint256[]"}],"name":"getExpiryAmount","outputs":[{"internalType":"uint96","name":"expiryAmount","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"staker","type":"address"}],"name":"getIdsForClaimRewards","outputs":[{"internalType":"uint256[]","name":"n","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"staker","type":"address"},{"internalType":"uint256","name":"n","type":"uint256"}],"name":"getIsStakeMature","outputs":[{"internalType":"bool","name":"isMature","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"staker","type":"address"}],"name":"getNumberOfStakes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"staker","type":"address"},{"internalType":"uint256[]","name":"n","type":"uint256[]"}],"name":"getStakeAmount","outputs":[{"internalType":"uint96","name":"amount","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"staker","type":"address"},{"internalType":"uint256","name":"n","type":"uint256"}],"name":"getStakingInfo","outputs":[{"components":[{"internalType":"enum Stake.StakingPeriod","name":"period","type":"uint8"},{"internalType":"uint40","name":"startTime","type":"uint40"},{"internalType":"uint40","name":"expiryTime","type":"uint40"},{"internalType":"uint96","name":"amount","type":"uint96"},{"internalType":"uint96","name":"expiryAmount","type":"uint96"},{"internalType":"uint96","name":"claimedAmount","type":"uint96"},{"internalType":"uint96","name":"gStfxAmount","type":"uint96"},{"internalType":"bool","name":"isCompleted","type":"bool"}],"internalType":"struct Stake.StakingInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStats","outputs":[{"internalType":"uint96","name":"","type":"uint96"},{"internalType":"uint96","name":"","type":"uint96"},{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"staker","type":"address"}],"name":"getStatsPerStaker","outputs":[{"internalType":"uint96","name":"amount","type":"uint96"},{"internalType":"uint96","name":"expiryAmount","type":"uint96"},{"internalType":"uint96","name":"claimedAmount","type":"uint96"},{"internalType":"uint96","name":"accruedRewards","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"","type":"uint8"}],"name":"interestRate","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"n","type":"uint256"},{"internalType":"enum Stake.StakingPeriod","name":"period","type":"uint8"}],"name":"restake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardsToDate","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint96","name":"amount","type":"uint96"},{"internalType":"enum Stake.StakingPeriod","name":"period","type":"uint8"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"stakingInfo","outputs":[{"internalType":"enum Stake.StakingPeriod","name":"period","type":"uint8"},{"internalType":"uint40","name":"startTime","type":"uint40"},{"internalType":"uint40","name":"expiryTime","type":"uint40"},{"internalType":"uint96","name":"amount","type":"uint96"},{"internalType":"uint96","name":"expiryAmount","type":"uint96"},{"internalType":"uint96","name":"claimedAmount","type":"uint96"},{"internalType":"uint96","name":"gStfxAmount","type":"uint96"},{"internalType":"bool","name":"isCompleted","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStaked","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"n","type":"uint256[]"}],"name":"unstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"burn","type":"address"}],"name":"updateBurnAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"percent","type":"uint32"}],"name":"updateBurnPercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b5060405162003fbb38038062003fbb8339810160408190526200003491620000d7565b6040805180820182526005808252640cea6a88cb60db1b6020808401829052845180860190955291845290830152906003620000718382620001ae565b506004620000808282620001ae565b505060058054336001600160a01b031991821617909155600680546001600160a01b03949094166001600160c01b03199094169390931761027160a51b17909255506007805461dead92169190911790556200027a565b600060208284031215620000ea57600080fd5b81516001600160a01b03811681146200010257600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200013457607f821691505b6020821081036200015557634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620001a957600081815260208120601f850160051c81016020861015620001845750805b601f850160051c820191505b81811015620001a55782815560010162000190565b5050505b505050565b81516001600160401b03811115620001ca57620001ca62000109565b620001e281620001db84546200011f565b846200015b565b602080601f8311600181146200021a5760008415620002015750858301515b600019600386901b1c1916600185901b178555620001a5565b600085815260208120601f198616915b828110156200024b578886015182559484019460019091019084016200022a565b50858210156200026a5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b613d31806200028a6000396000f3fe608060405234801561001057600080fd5b506004361061028a5760003560e01c80638da5cb5b1161015c578063c59d4847116100ce578063dfb5a8c511610087578063dfb5a8c514610692578063e449f341146106b8578063e59373dd146106cb578063eda186f6146106de578063f42f761c146106f1578063fc0c546a1461070457600080fd5b8063c59d4847146105f7578063ca0e2d1914610633578063ca0f089914610646578063ce72257814610659578063d4d9954f1461066c578063dd62ed3e1461067f57600080fd5b8063a457c2d711610120578063a457c2d714610584578063a9059cbb146102f5578063a9e42e3514610597578063ade19cf7146105aa578063b5906559146105bd578063c06fcba0146105d057600080fd5b80638da5cb5b146105235780638e344f371461053657806395d89b41146105495780639e4be7bf146105515780639e740bb11461056457600080fd5b806348d90f6b116102005780636bd89cdd116101b95780636bd89cdd146104755780636efd61c81461048857806370a08231146104a257806370d5ae05146104cb578063817b1cd2146104f657806386e13c171461051057600080fd5b806348d90f6b146103c357806351cff8d9146103d65780635eac6239146103e95780636053854d146103fc578063625ef1731461041c5780636ba4c1381461046257600080fd5b806318160ddd1161025257806318160ddd1461032d5780631c54a0d41461033f57806323b872dd14610352578063313ce56714610360578063395093511461036f5780634574cefb1461038257600080fd5b806303807ee51461028f57806304238994146102c057806306fdde03146102e0578063095ea7b3146102f557806313af403514610318575b600080fd5b6006546102a690600160a01b900463ffffffff1681565b60405163ffffffff90911681526020015b60405180910390f35b6102d36102ce3660046135d2565b610717565b6040516102b791906136a3565b6102e86108a6565b6040516102b791906136f2565b610308610303366004613740565b610938565b60405190151581526020016102b7565b61032b6103263660046135d2565b610953565b005b6002545b6040519081526020016102b7565b61032b61034d366004613779565b6109ef565b6103086103033660046137a5565b604051601281526020016102b7565b61030861037d366004613740565b610d23565b6103ab6103903660046137e1565b600a602052600090815260409020546001600160601b031681565b6040516001600160601b0390911681526020016102b7565b6103ab6103d13660046138b5565b610d51565b61032b6103e43660046135d2565b610ead565b61032b6103f7366004613903565b611004565b61040f61040a366004613740565b6112c0565b6040516102b79190613938565b61042f61042a3660046135d2565b6113b3565b604080516001600160601b03958616815293851660208501529184169183019190915290911660608201526080016102b7565b61032b610470366004613903565b611516565b61032b6104833660046135d2565b6118a3565b6008546103ab90600160601b90046001600160601b031681565b6103316104b03660046135d2565b6001600160a01b031660009081526020819052604090205490565b6007546104de906001600160a01b031681565b6040516001600160a01b0390911681526020016102b7565b6007546103ab90600160a01b90046001600160601b031681565b6103ab61051e366004613740565b611918565b6005546104de906001600160a01b031681565b61032b61054436600461395e565b611aaf565b6102e8611e3b565b61032b61055f366004613988565b611e4a565b6105776105723660046135d2565b611f48565b6040516102b791906139ed565b610308610592366004613740565b612089565b6103ab6105a5366004613740565b612114565b6103ab6105b83660046138b5565b612295565b6103086105cb366004613740565b6123ec565b6105e36105de366004613740565b612444565b6040516102b7989796959493929190613a00565b60075460085460408051600160a01b9093046001600160601b039081168452600160601b830481166020850152909116908201526060016102b7565b6103ab6106413660046138b5565b6124c9565b61032b610654366004613a72565b6126c8565b6008546103ab906001600160601b031681565b6103ab61067a3660046138b5565b612775565b61033161068d366004613a8d565b612975565b6102a66106a03660046137e1565b600b6020526000908152604090205463ffffffff1681565b61032b6106c6366004613903565b6129a0565b61032b6106d9366004613ab7565b612df8565b6103ab6106ec3660046138b5565b612edd565b6103316106ff3660046135d2565b613032565b6006546104de906001600160a01b031681565b6001600160a01b0381166000908152600960205260408120546060918167ffffffffffffffff81111561074c5761074c613804565b60405190808252806020026020018201604052801561078557816020015b610772613575565b81526020019060019003908161076a5790505b50905060005b8281101561089e576001600160a01b03851660009081526009602052604090208054829081106107bd576107bd613ae1565b600091825260209091206040805161010081019091526003909202018054829060ff1660048111156107f1576107f16135f4565b6004811115610802576108026135f4565b81528154610100810464ffffffffff9081166020840152600160301b8204166040830152600160581b90046001600160601b03908116606083015260018301548082166080840152600160601b90819004821660a084015260029093015490811660c08301529190910460ff16151560e090910152825183908390811061088b5761088b613ae1565b602090810291909101015260010161078b565b509392505050565b6060600380546108b590613af7565b80601f01602080910402602001604051908101604052809291908181526020018280546108e190613af7565b801561092e5780601f106109035761010080835404028352916020019161092e565b820191906000526020600020905b81548152906001019060200180831161091157829003601f168201915b5050505050905090565b6000604051639cbe235760e01b815260040160405180910390fd5b6005546001600160a01b0316331461097e576040516330cd747160e01b815260040160405180910390fd5b6001600160a01b0381166109a55760405163d92e233d60e01b815260040160405180910390fd5b600580546001600160a01b0319166001600160a01b0383169081179091556040517f803b4c11a31d301bf4cd4a8af43f64cc758f16cfb69a35cb2ff60916ff017dab90600090a250565b60006109fa33613032565b9050808310610a1c576040516302e7c60160e31b815260040160405180910390fd5b6000610a2833856112c0565b9050806040015164ffffffffff164210610a555760405163d3436bcb60e01b815260040160405180910390fd5b80516004811115610a6857610a686135f4565b60ff16836004811115610a7d57610a7d6135f4565b60ff161015610a9f576040516365fce3a760e11b815260040160405180910390fd5b6000610aab3386612114565b90506000610ad78360a0015183610ac29190613b47565b8460600151610ad19190613b67565b8661304d565b3360009081526009602052604090208054919250829188908110610afd57610afd613ae1565b6000918252602090912082516003909202018054909190829060ff19166001836004811115610b2e57610b2e6135f4565b021790555060208201518154604084015160608501516affffffffffffffffffff001990921661010064ffffffffff948516026affffffffff000000000000191617600160301b9390911692909202919091176bffffffffffffffffffffffff60581b1916600160581b6001600160601b0392831602178255608083015160018301805460a0808701519385166001600160c01b031990921691909117600160601b93851684021790915560c08501516002909401805460e090960151949093166cffffffffffffffffffffffffff199095169490941792151502919091179055830151610c1c9083613b47565b60078054601490610c3e908490600160a01b90046001600160601b0316613b67565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550610c88338460c001518360c00151610c7a9190613b47565b6001600160601b0316613188565b336001600160a01b03167f1c83975eb7d62799fd03db85395e9949a70a760b1e5d2be50180bd95efb2cd9f8783606001518460800151856040015186600001516004811115610cd957610cd96135f4565b604080519586526001600160601b039485166020870152929093169184019190915264ffffffffff16606083015260ff16608082015260a0015b60405180910390a2505050505050565b600033610d45818585610d368383612975565b610d409190613b87565b613247565b60019150505b92915050565b6000610d5c83613032565b82511115610d80576040516001621398b960e31b0319815260040160405180910390fd5b60005b8251811015610ea6576001600160a01b03841660009081526009602052604081208451859084908110610db857610db8613ae1565b602002602001015181548110610dd057610dd0613ae1565b600091825260209091206040805161010081019091526003909202018054829060ff166004811115610e0457610e046135f4565b6004811115610e1557610e156135f4565b8152815464ffffffffff610100820481166020840152600160301b82041660408301526001600160601b03600160581b909104811660608301526001830154808216608080850191909152600160601b91829004831660a085015260029094015491821660c084015260ff910416151560e090910152810151909150610e9b9084613b67565b925050600101610d83565b5092915050565b6005546001600160a01b03163314610ed8576040516330cd747160e01b815260040160405180910390fd5b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa158015610f1f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f439190613b9a565b60055460405163a9059cbb60e01b81526001600160a01b0391821660048201526024810183905291925083169063a9059cbb906044016020604051808303816000875af1158015610f98573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fbc9190613bb3565b50816001600160a01b03167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a942436482604051610ff891815260200190565b60405180910390a25050565b600061100f33613032565b90508082511115611036576040516001621398b960e31b0319815260040160405180910390fd5b6000805b8351811015611190578284828151811061105657611056613ae1565b60200260200101511061107c576040516302e7c60160e31b815260040160405180910390fd5b60006110a13386848151811061109457611094613ae1565b60200260200101516112c0565b905060006110c8338785815181106110bb576110bb613ae1565b6020026020010151612114565b9050806001600160601b03168260a001516001600160601b03161080156110f157508160e00151155b156111865760a08201516111058183613b47565b61110f9086613b67565b3360009081526009602052604090208851919650839189908790811061113757611137613ae1565b60200260200101518154811061114f5761114f613ae1565b9060005260206000209060030201600101600c6101000a8154816001600160601b0302191690836001600160601b03160217905550505b505060010161103a565b50806001600160601b03166000036111bb576040516373380d9960e01b815260040160405180910390fd5b806008600c8282829054906101000a90046001600160601b03166111df9190613b67565b82546001600160601b039182166101009390930a92830291909202199091161790555060065460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb906112349033908590600401613bd5565b6020604051808303816000875af1158015611253573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112779190613bb3565b50336001600160a01b03167fcf3dc675b372b9480b8de78cb48a2d2fe2aae7ade838c6d9025ab9c0e1b45a6b84836040516112b3929190613bf7565b60405180910390a2505050565b6112c8613575565b6001600160a01b03831660009081526009602052604090208054839081106112f2576112f2613ae1565b600091825260209091206040805161010081019091526003909202018054829060ff166004811115611326576113266135f4565b6004811115611337576113376135f4565b81528154610100810464ffffffffff9081166020840152600160301b8204166040830152600160581b90046001600160601b03908116606083015260018301548082166080840152600160601b90819004821660a084015260029093015490811660c08301529190910460ff16151560e0909101529392505050565b60008060008060006113c486613032565b905060005b8181101561150d576001600160a01b03871660009081526009602052604081208054839081106113fb576113fb613ae1565b600091825260209091206040805161010081019091526003909202018054829060ff16600481111561142f5761142f6135f4565b6004811115611440576114406135f4565b81528154610100810464ffffffffff9081166020840152600160301b8204166040830152600160581b90046001600160601b0390811660608084019190915260018401548083166080850152600160601b90819004831660a085015260029094015491821660c084015292900460ff16151560e0909101528101519091506114c89088613b67565b96508060800151866114da9190613b67565b95508060a00151856114ec9190613b67565b94506114f88883612114565b6115029085613b67565b9350506001016113c9565b50509193509193565b60008060008060008061152833613032565b9050808751111561154f576040516001621398b960e31b0319815260040160405180910390fd5b60005b8751811015611781578188828151811061156e5761156e613ae1565b602002602001015110611594576040516302e7c60160e31b815260040160405180910390fd5b60006115ac338a848151811061109457611094613ae1565b9050806040015164ffffffffff164210156115da57604051632968c44760e21b815260040160405180910390fd5b8060e00151156115fd57604051635e72b67160e01b815260040160405180910390fd5b606081015161160c9089613b67565b975080608001518761161e9190613b67565b96508060a0015181608001516116349190613b47565b61163e9087613b67565b95508060a00151816060015182608001516116599190613b47565b6116639190613b47565b61166d9085613b67565b93508060c001518561167f9190613b67565b9450806060015181608001516116959190613b47565b3360009081526009602052604090208a518b90859081106116b8576116b8613ae1565b6020026020010151815481106116d0576116d0613ae1565b600091825260208083206001600390930201820180546001600160601b0395909516600160601b026bffffffffffffffffffffffff60601b19909516949094179093553382526009909252604090208a518b908590811061173357611733613ae1565b60200260200101518154811061174b5761174b613ae1565b600091825260209091206002600390920201018054911515600160601b0260ff60601b1990921691909117905550600101611552565b50816008600c8282829054906101000a90046001600160601b03166117a69190613b67565b92506101000a8154816001600160601b0302191690836001600160601b031602179055506117dd33846001600160601b031661336c565b60065460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9061180f9033908890600401613bd5565b6020604051808303816000875af115801561182e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118529190613bb3565b50336001600160a01b03167f3e6e14ff492fd2081343250baa4cbaa1950e574db4143f8ec0b33736b6ed2542888888886040516118929493929190613c22565b60405180910390a250505050505050565b6005546001600160a01b031633146118ce576040516330cd747160e01b815260040160405180910390fd5b600780546001600160a01b0319166001600160a01b0383169081179091556040517f6a94f93d0f80241b5d6e8b868e1df78fc5f8024f40f9b79643a6d62bfdf6424290600090a250565b6001600160a01b038216600090815260096020526040812080548291908490811061194557611945613ae1565b600091825260209091206040805161010081019091526003909202018054829060ff166004811115611979576119796135f4565b600481111561198a5761198a6135f4565b81528154610100810464ffffffffff9081166020840152600160301b82048116604080850191909152600160581b9092046001600160601b03908116606085015260018501548082166080860152600160601b90819004821660a086015260029095015490811660c08501529390930460ff16151560e0909201919091528201519192501642101580611a1e57508060e001515b15611a2c5760009150610ea6565b80602001518160400151611a409190613c5e565b611a549064ffffffffff16620186a0613c7c565b42826040015164ffffffffff16611a6b9190613c93565b6060830151600654611a93916001600160601b031690600160a01b900463ffffffff16613c7c565b611a9d9190613c7c565b611aa79190613ca6565b949350505050565b6006546040516370a0823160e01b81523360048201526001600160601b038416916001600160a01b0316906370a0823190602401602060405180830381865afa158015611b00573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b249190613b9a565b1015611b4357604051631d00495b60e31b815260040160405180910390fd5b600a6000826004811115611b5957611b596135f4565b60ff16815260208101919091526040016000908120546001600160601b03169003611b97576040516365fce3a760e11b815260040160405180910390fd5b6000611ba3838361304d565b3360009081526009602090815260408220805460018181018355918452919092208351600390920201805493945084939092839160ff191690836004811115611bee57611bee6135f4565b021790555060208201518154604084015160608501516affffffffffffffffffff001990921661010064ffffffffff948516026affffffffff000000000000191617600160301b9390911692909202919091176bffffffffffffffffffffffff60581b1916600160581b6001600160601b0392831602178255608083015160018301805460a08601519284166001600160c01b031990911617600160601b928416830217905560c08401516002909301805460e0909501519383166cffffffffffffffffffffffffff19909516949094179215150291909117909155600780548592601491611ce6918591600160a01b900416613b67565b82546101009290920a6001600160601b038181021990931691831602179091553360008181526009602052604090205460c0850151909350611d289216613188565b6006546040516323b872dd60e01b81523360048201523060248201526001600160601b03861660448201526001600160a01b03909116906323b872dd906064016020604051808303816000875af1158015611d87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dab9190613bb3565b50337f1c83975eb7d62799fd03db85395e9949a70a760b1e5d2be50180bd95efb2cd9f611dd9600184613c93565b8685608001518660400151886004811115611df657611df66135f4565b604080519586526001600160601b039485166020870152929093168483015264ffffffffff16606084015260ff9091166080830152519081900360a00190a250505050565b6060600480546108b590613af7565b6005546001600160a01b03163314611e75576040516330cd747160e01b815260040160405180910390fd5b6001816001600160601b03161015611ea057604051631f2a200560e01b815260040160405180910390fd5b80600a6000846004811115611eb757611eb76135f4565b60ff168152602081019190915260400160002080546bffffffffffffffffffffffff19166001600160601b03929092169190911790557f578b86c872c0807eedb1a1cb5ffd80b43c061f0b0c8b305db3e5f0a5737fb1fa826004811115611f2057611f206135f4565b6040805160ff90921682526001600160601b0384166020830152015b60405180910390a15050565b60606000611f5583613032565b905060005b81811015612082576001600160a01b0384166000908152600960205260408120805483908110611f8c57611f8c613ae1565b600091825260209091206040805161010081019091526003909202018054829060ff166004811115611fc057611fc06135f4565b6004811115611fd157611fd16135f4565b81528154610100810464ffffffffff9081166020840152600160301b8204166040830152600160581b90046001600160601b03908116606083015260018301548082166080840152600160601b90819004821660a084015260029093015490811660c08301529190910460ff16151560e0918201528101519091501580156120635750806040015164ffffffffff1642105b1561207957835160010180855260200284018290525b50600101611f5a565b5050919050565b600033816120978286612975565b9050838110156120fc5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084015b60405180910390fd5b6121098286868403613247565b506001949350505050565b6001600160a01b038216600090815260096020526040812080548291908490811061214157612141613ae1565b600091825260209091206040805161010081019091526003909202018054829060ff166004811115612175576121756135f4565b6004811115612186576121866135f4565b81528154610100810464ffffffffff9081166020840152600160301b8204166040830152600160581b90046001600160601b03908116606083015260018301548082166080840152600160601b90819004821660a084015260029093015490811660c08301529190910460ff16151560e0918201528101519091501561220f5760009150610ea6565b806040015164ffffffffff16421061223c57806060015181608001516122359190613b47565b9150610ea6565b806020015181604001516122509190613c5e565b64ffffffffff16816020015164ffffffffff164261226e9190613c93565b826060015183608001516122829190613b47565b6001600160601b0316611a9d9190613c7c565b60006122a083613032565b825111156122c4576040516001621398b960e31b0319815260040160405180910390fd5b60005b8251811015610ea6576001600160a01b038416600090815260096020526040812084518590849081106122fc576122fc613ae1565b60200260200101518154811061231457612314613ae1565b600091825260209091206040805161010081019091526003909202018054829060ff166004811115612348576123486135f4565b6004811115612359576123596135f4565b81528154610100810464ffffffffff9081166020840152600160301b8204166040830152600160581b90046001600160601b0390811660608084019190915260018401548083166080850152600160601b90819004831660a085015260029094015491821660c084015292900460ff16151560e0909101528101519091506123e19084613b67565b9250506001016122c7565b6001600160a01b038216600090815260096020526040812080548390811061241657612416613ae1565b6000918252602090912060039091020154600160301b900464ffffffffff164210610d4b5750600192915050565b6009602052816000526040600020818154811061246057600080fd5b600091825260209091206003909102018054600182015460029092015460ff808316955064ffffffffff610100840481169550600160301b840416936001600160601b03600160581b90940484169381811693600160601b928390048216939181169290041688565b60006124d483613032565b825111156124f8576040516001621398b960e31b0319815260040160405180910390fd5b60005b8251811015610ea6576001600160a01b0384166000908152600960205260408120845185908490811061253057612530613ae1565b60200260200101518154811061254857612548613ae1565b600091825260209091206040805161010081019091526003909202018054829060ff16600481111561257c5761257c6135f4565b600481111561258d5761258d6135f4565b81528154610100810464ffffffffff9081166020840152600160301b8204166040830152600160581b90046001600160601b03908116606083015260018301548082166080840152600160601b90819004821660a084015260029093015490811660c08301529190910460ff16151560e0918201528101519091501561261f57612618600084613b67565b92506126bf565b806040015164ffffffffff16421061264f57806060015181608001516126459190613b47565b6126189084613b67565b806020015181604001516126639190613c5e565b64ffffffffff16816020015164ffffffffff16426126819190613c93565b826060015183608001516126959190613b47565b6001600160601b03166126a89190613c7c565b6126b29190613ca6565b6126bc9084613b67565b92505b506001016124fb565b6005546001600160a01b031633146126f3576040516330cd747160e01b815260040160405180910390fd5b60018163ffffffff16101561271b57604051631f2a200560e01b815260040160405180910390fd5b6006805463ffffffff60a01b1916600160a01b63ffffffff8416908102919091179091556040519081527f714f865fe90480bc6f60d9b15d54b5a3c34526bd214657b30eacbecb2f770b4c9060200160405180910390a150565b600061278083613032565b825111156127a4576040516001621398b960e31b0319815260040160405180910390fd5b60005b8251811015610ea6576001600160a01b038416600090815260096020526040812084518590849081106127dc576127dc613ae1565b6020026020010151815481106127f4576127f4613ae1565b600091825260209091206040805161010081019091526003909202018054829060ff166004811115612828576128286135f4565b6004811115612839576128396135f4565b81528154610100810464ffffffffff9081166020840152600160301b82048116604080850191909152600160581b9092046001600160601b03908116606085015260018501548082166080860152600160601b90819004821660a086015260029095015490811660c08501529390930460ff16151560e09092019190915282015191925016421015806128cd57508060e001515b156128e4576128dd600084613b67565b925061296c565b806020015181604001516128f89190613c5e565b61290c9064ffffffffff16620186a0613c7c565b42826040015164ffffffffff166129239190613c93565b606083015160065461294b916001600160601b031690600160a01b900463ffffffff16613c7c565b6129559190613c7c565b61295f9190613ca6565b6129699084613b67565b92505b506001016127a7565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60006129ab33613032565b905080825111156129d2576040516001621398b960e31b0319815260040160405180910390fd5b60008060008060005b8651811015612c2757858782815181106129f7576129f7613ae1565b602002602001015110612a1d576040516302e7c60160e31b815260040160405180910390fd5b6000612a353389848151811061109457611094613ae1565b9050806040015164ffffffffff164210612a625760405163d3436bcb60e01b815260040160405180910390fd5b8060e0015115612a8557604051635e72b67160e01b815260040160405180910390fd5b6000612a9d338a85815181106110bb576110bb613ae1565b90506000612ac4338b8681518110612ab757612ab7613ae1565b6020026020010151611918565b90508260a0015182612ad69190613b47565b612ae09089613b67565b97508260a0015182612af29190613b47565b818460600151612b029190613b47565b612b0c9190613b67565b612b169088613b67565b9650612b228187613b67565b95508260c0015185612b349190613b67565b3360009081526009602052604090208b5191965083918c9087908110612b5c57612b5c613ae1565b602002602001015181548110612b7457612b74613ae1565b600091825260208083206001600390930201820180546001600160601b0395909516600160601b026bffffffffffffffffffffffff60601b19909516949094179093553382526009909252604090208b518c9087908110612bd757612bd7613ae1565b602002602001015181548110612bef57612bef613ae1565b600091825260209091206002600390920201018054911515600160601b0260ff60601b199092169190911790555050506001016129db565b50836008600c8282829054906101000a90046001600160601b0316612c4c9190613b67565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555081600860008282829054906101000a90046001600160601b0316612c949190613b67565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550612ccb33826001600160601b031661336c565b60065460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb90612cfd9033908790600401613bd5565b6020604051808303816000875af1158015612d1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d409190613bb3565b5060065460075460405163a9059cbb60e01b81526001600160a01b039283169263a9059cbb92612d77929116908690600401613bd5565b6020604051808303816000875af1158015612d96573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dba9190613bb3565b50336001600160a01b03167fd8a0f675e5c0d97fc6b4eace3d3f8f0d844d7acd23417c1d76d8b4fc9e616e43878585604051610d1393929190613cc8565b6005546001600160a01b03163314612e23576040516330cd747160e01b815260040160405180910390fd5b60018163ffffffff161015612e4b57604051631f2a200560e01b815260040160405180910390fd5b80600b6000846004811115612e6257612e626135f4565b60ff1681526020810191909152604001600020805463ffffffff191663ffffffff929092169190911790557fabeb6b6d39f1fc7eb48ffdc5f1f76e68c7d4f81d9dbff3295aaa06e4779015c4826004811115612ec057612ec06135f4565b6040805160ff909216825263ffffffff8416602083015201611f3c565b6000612ee883613032565b82511115612f0c576040516001621398b960e31b0319815260040160405180910390fd5b60005b8251811015610ea6576001600160a01b03841660009081526009602052604081208451859084908110612f4457612f44613ae1565b602002602001015181548110612f5c57612f5c613ae1565b600091825260209091206040805161010081019091526003909202018054829060ff166004811115612f9057612f906135f4565b6004811115612fa157612fa16135f4565b8152815464ffffffffff610100820481166020840152600160301b82041660408301526001600160601b03600160581b9091048116606083015260018301548082166080840152600160601b90819004821660a08085019190915260029094015491821660c084015260ff910416151560e0909101528101519091506130279084613b67565b925050600101612f0f565b6001600160a01b031660009081526009602052604090205490565b613055613575565b64ffffffffff421660208201526001600160601b0383166060820181905268056bc75e2d63100000600a6000856004811115613093576130936135f4565b60ff1681526020810191909152604001600020546130be906001600160601b03908116908716613c7c565b6130c89190613ca6565b6130d29190613b87565b6001600160601b03166080820152808260048111156130f3576130f36135f4565b90816004811115613106576131066135f4565b90525061311282613496565b64ffffffffff16604082015260608101516103e8906001600160601b0316600b6000856004811115613146576131466135f4565b60ff16815260208101919091526040016000205461316a919063ffffffff16613c7c565b6131749190613ca6565b6001600160601b031660c082015292915050565b6001600160a01b0382166131de5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016120f3565b80600260008282546131f09190613b87565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6001600160a01b0383166132a95760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016120f3565b6001600160a01b03821661330a5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016120f3565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6001600160a01b0382166133cc5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b60648201526084016120f3565b6001600160a01b038216600090815260208190526040902054818110156134405760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b60648201526084016120f3565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910161335f565b6000808260048111156134ab576134ab6135f4565b036134bd57610d4b4262278d00613b87565b60018260048111156134d1576134d16135f4565b036134e357610d4b426276a700613b87565b60028260048111156134f7576134f76135f4565b0361350957610d4b4262ed4e00613b87565b600382600481111561351d5761351d6135f4565b0361353057610d4b426301e13380613b87565b6004826004811115613544576135446135f4565b0361355757610d4b426303c26700613b87565b6040516365fce3a760e11b815260040160405180910390fd5b919050565b604080516101008101909152806000815260006020820181905260408201819052606082018190526080820181905260a0820181905260c0820181905260e09091015290565b80356001600160a01b038116811461357057600080fd5b6000602082840312156135e457600080fd5b6135ed826135bb565b9392505050565b634e487b7160e01b600052602160045260246000fd5b6005811061362857634e487b7160e01b600052602160045260246000fd5b9052565b61363782825161360a565b602081015164ffffffffff8082166020850152806040840151166040850152505060608101516001600160601b0380821660608501528060808401511660808501528060a08401511660a08501528060c08401511660c0850152505060e0810151151560e08301525050565b6020808252825182820181905260009190848201906040850190845b818110156136e6576136d283855161362c565b9284019261010092909201916001016136bf565b50909695505050505050565b600060208083528351808285015260005b8181101561371f57858101830151858201604001528201613703565b506000604082860101526040601f19601f8301168501019250505092915050565b6000806040838503121561375357600080fd5b61375c836135bb565b946020939093013593505050565b80356005811061357057600080fd5b6000806040838503121561378c57600080fd5b8235915061379c6020840161376a565b90509250929050565b6000806000606084860312156137ba57600080fd5b6137c3846135bb565b92506137d1602085016135bb565b9150604084013590509250925092565b6000602082840312156137f357600080fd5b813560ff811681146135ed57600080fd5b634e487b7160e01b600052604160045260246000fd5b600082601f83011261382b57600080fd5b8135602067ffffffffffffffff8083111561384857613848613804565b8260051b604051601f19603f8301168101818110848211171561386d5761386d613804565b60405293845285810183019383810192508785111561388b57600080fd5b83870191505b848210156138aa57813583529183019190830190613891565b979650505050505050565b600080604083850312156138c857600080fd5b6138d1836135bb565b9150602083013567ffffffffffffffff8111156138ed57600080fd5b6138f98582860161381a565b9150509250929050565b60006020828403121561391557600080fd5b813567ffffffffffffffff81111561392c57600080fd5b611aa78482850161381a565b6101008101610d4b828461362c565b80356001600160601b038116811461357057600080fd5b6000806040838503121561397157600080fd5b61397a83613947565b915061379c6020840161376a565b6000806040838503121561399b57600080fd5b6139a48361376a565b915061379c60208401613947565b600081518084526020808501945080840160005b838110156139e2578151875295820195908201906001016139c6565b509495945050505050565b6020815260006135ed60208301846139b2565b6101008101613a0f828b61360a565b64ffffffffff98891660208301529690971660408801526001600160601b039485166060880152928416608087015290831660a086015290911660c0840152151560e090920191909152919050565b803563ffffffff8116811461357057600080fd5b600060208284031215613a8457600080fd5b6135ed82613a5e565b60008060408385031215613aa057600080fd5b613aa9836135bb565b915061379c602084016135bb565b60008060408385031215613aca57600080fd5b613ad38361376a565b915061379c60208401613a5e565b634e487b7160e01b600052603260045260246000fd5b600181811c90821680613b0b57607f821691505b602082108103613b2b57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b6001600160601b03828116828216039080821115610ea657610ea6613b31565b6001600160601b03818116838216019080821115610ea657610ea6613b31565b80820180821115610d4b57610d4b613b31565b600060208284031215613bac57600080fd5b5051919050565b600060208284031215613bc557600080fd5b815180151581146135ed57600080fd5b6001600160a01b039290921682526001600160601b0316602082015260400190565b604081526000613c0a60408301856139b2565b90506001600160601b03831660208301529392505050565b608081526000613c3560808301876139b2565b6001600160601b0395861660208401529385166040830152509216606090920191909152919050565b64ffffffffff828116828216039080821115610ea657610ea6613b31565b8082028115828204841417610d4b57610d4b613b31565b81810381811115610d4b57610d4b613b31565b600082613cc357634e487b7160e01b600052601260045260246000fd5b500490565b606081526000613cdb60608301866139b2565b6001600160601b039485166020840152929093166040909101529291505056fea2646970667358221220ec60376bf8c26f8d1e41b407803a3afe47ab4354ed53fa1c2bf7c0101fb4800364736f6c634300081300330000000000000000000000009343e24716659a3551eb10aff9472a2dcad5db2d
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061028a5760003560e01c80638da5cb5b1161015c578063c59d4847116100ce578063dfb5a8c511610087578063dfb5a8c514610692578063e449f341146106b8578063e59373dd146106cb578063eda186f6146106de578063f42f761c146106f1578063fc0c546a1461070457600080fd5b8063c59d4847146105f7578063ca0e2d1914610633578063ca0f089914610646578063ce72257814610659578063d4d9954f1461066c578063dd62ed3e1461067f57600080fd5b8063a457c2d711610120578063a457c2d714610584578063a9059cbb146102f5578063a9e42e3514610597578063ade19cf7146105aa578063b5906559146105bd578063c06fcba0146105d057600080fd5b80638da5cb5b146105235780638e344f371461053657806395d89b41146105495780639e4be7bf146105515780639e740bb11461056457600080fd5b806348d90f6b116102005780636bd89cdd116101b95780636bd89cdd146104755780636efd61c81461048857806370a08231146104a257806370d5ae05146104cb578063817b1cd2146104f657806386e13c171461051057600080fd5b806348d90f6b146103c357806351cff8d9146103d65780635eac6239146103e95780636053854d146103fc578063625ef1731461041c5780636ba4c1381461046257600080fd5b806318160ddd1161025257806318160ddd1461032d5780631c54a0d41461033f57806323b872dd14610352578063313ce56714610360578063395093511461036f5780634574cefb1461038257600080fd5b806303807ee51461028f57806304238994146102c057806306fdde03146102e0578063095ea7b3146102f557806313af403514610318575b600080fd5b6006546102a690600160a01b900463ffffffff1681565b60405163ffffffff90911681526020015b60405180910390f35b6102d36102ce3660046135d2565b610717565b6040516102b791906136a3565b6102e86108a6565b6040516102b791906136f2565b610308610303366004613740565b610938565b60405190151581526020016102b7565b61032b6103263660046135d2565b610953565b005b6002545b6040519081526020016102b7565b61032b61034d366004613779565b6109ef565b6103086103033660046137a5565b604051601281526020016102b7565b61030861037d366004613740565b610d23565b6103ab6103903660046137e1565b600a602052600090815260409020546001600160601b031681565b6040516001600160601b0390911681526020016102b7565b6103ab6103d13660046138b5565b610d51565b61032b6103e43660046135d2565b610ead565b61032b6103f7366004613903565b611004565b61040f61040a366004613740565b6112c0565b6040516102b79190613938565b61042f61042a3660046135d2565b6113b3565b604080516001600160601b03958616815293851660208501529184169183019190915290911660608201526080016102b7565b61032b610470366004613903565b611516565b61032b6104833660046135d2565b6118a3565b6008546103ab90600160601b90046001600160601b031681565b6103316104b03660046135d2565b6001600160a01b031660009081526020819052604090205490565b6007546104de906001600160a01b031681565b6040516001600160a01b0390911681526020016102b7565b6007546103ab90600160a01b90046001600160601b031681565b6103ab61051e366004613740565b611918565b6005546104de906001600160a01b031681565b61032b61054436600461395e565b611aaf565b6102e8611e3b565b61032b61055f366004613988565b611e4a565b6105776105723660046135d2565b611f48565b6040516102b791906139ed565b610308610592366004613740565b612089565b6103ab6105a5366004613740565b612114565b6103ab6105b83660046138b5565b612295565b6103086105cb366004613740565b6123ec565b6105e36105de366004613740565b612444565b6040516102b7989796959493929190613a00565b60075460085460408051600160a01b9093046001600160601b039081168452600160601b830481166020850152909116908201526060016102b7565b6103ab6106413660046138b5565b6124c9565b61032b610654366004613a72565b6126c8565b6008546103ab906001600160601b031681565b6103ab61067a3660046138b5565b612775565b61033161068d366004613a8d565b612975565b6102a66106a03660046137e1565b600b6020526000908152604090205463ffffffff1681565b61032b6106c6366004613903565b6129a0565b61032b6106d9366004613ab7565b612df8565b6103ab6106ec3660046138b5565b612edd565b6103316106ff3660046135d2565b613032565b6006546104de906001600160a01b031681565b6001600160a01b0381166000908152600960205260408120546060918167ffffffffffffffff81111561074c5761074c613804565b60405190808252806020026020018201604052801561078557816020015b610772613575565b81526020019060019003908161076a5790505b50905060005b8281101561089e576001600160a01b03851660009081526009602052604090208054829081106107bd576107bd613ae1565b600091825260209091206040805161010081019091526003909202018054829060ff1660048111156107f1576107f16135f4565b6004811115610802576108026135f4565b81528154610100810464ffffffffff9081166020840152600160301b8204166040830152600160581b90046001600160601b03908116606083015260018301548082166080840152600160601b90819004821660a084015260029093015490811660c08301529190910460ff16151560e090910152825183908390811061088b5761088b613ae1565b602090810291909101015260010161078b565b509392505050565b6060600380546108b590613af7565b80601f01602080910402602001604051908101604052809291908181526020018280546108e190613af7565b801561092e5780601f106109035761010080835404028352916020019161092e565b820191906000526020600020905b81548152906001019060200180831161091157829003601f168201915b5050505050905090565b6000604051639cbe235760e01b815260040160405180910390fd5b6005546001600160a01b0316331461097e576040516330cd747160e01b815260040160405180910390fd5b6001600160a01b0381166109a55760405163d92e233d60e01b815260040160405180910390fd5b600580546001600160a01b0319166001600160a01b0383169081179091556040517f803b4c11a31d301bf4cd4a8af43f64cc758f16cfb69a35cb2ff60916ff017dab90600090a250565b60006109fa33613032565b9050808310610a1c576040516302e7c60160e31b815260040160405180910390fd5b6000610a2833856112c0565b9050806040015164ffffffffff164210610a555760405163d3436bcb60e01b815260040160405180910390fd5b80516004811115610a6857610a686135f4565b60ff16836004811115610a7d57610a7d6135f4565b60ff161015610a9f576040516365fce3a760e11b815260040160405180910390fd5b6000610aab3386612114565b90506000610ad78360a0015183610ac29190613b47565b8460600151610ad19190613b67565b8661304d565b3360009081526009602052604090208054919250829188908110610afd57610afd613ae1565b6000918252602090912082516003909202018054909190829060ff19166001836004811115610b2e57610b2e6135f4565b021790555060208201518154604084015160608501516affffffffffffffffffff001990921661010064ffffffffff948516026affffffffff000000000000191617600160301b9390911692909202919091176bffffffffffffffffffffffff60581b1916600160581b6001600160601b0392831602178255608083015160018301805460a0808701519385166001600160c01b031990921691909117600160601b93851684021790915560c08501516002909401805460e090960151949093166cffffffffffffffffffffffffff199095169490941792151502919091179055830151610c1c9083613b47565b60078054601490610c3e908490600160a01b90046001600160601b0316613b67565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550610c88338460c001518360c00151610c7a9190613b47565b6001600160601b0316613188565b336001600160a01b03167f1c83975eb7d62799fd03db85395e9949a70a760b1e5d2be50180bd95efb2cd9f8783606001518460800151856040015186600001516004811115610cd957610cd96135f4565b604080519586526001600160601b039485166020870152929093169184019190915264ffffffffff16606083015260ff16608082015260a0015b60405180910390a2505050505050565b600033610d45818585610d368383612975565b610d409190613b87565b613247565b60019150505b92915050565b6000610d5c83613032565b82511115610d80576040516001621398b960e31b0319815260040160405180910390fd5b60005b8251811015610ea6576001600160a01b03841660009081526009602052604081208451859084908110610db857610db8613ae1565b602002602001015181548110610dd057610dd0613ae1565b600091825260209091206040805161010081019091526003909202018054829060ff166004811115610e0457610e046135f4565b6004811115610e1557610e156135f4565b8152815464ffffffffff610100820481166020840152600160301b82041660408301526001600160601b03600160581b909104811660608301526001830154808216608080850191909152600160601b91829004831660a085015260029094015491821660c084015260ff910416151560e090910152810151909150610e9b9084613b67565b925050600101610d83565b5092915050565b6005546001600160a01b03163314610ed8576040516330cd747160e01b815260040160405180910390fd5b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa158015610f1f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f439190613b9a565b60055460405163a9059cbb60e01b81526001600160a01b0391821660048201526024810183905291925083169063a9059cbb906044016020604051808303816000875af1158015610f98573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fbc9190613bb3565b50816001600160a01b03167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a942436482604051610ff891815260200190565b60405180910390a25050565b600061100f33613032565b90508082511115611036576040516001621398b960e31b0319815260040160405180910390fd5b6000805b8351811015611190578284828151811061105657611056613ae1565b60200260200101511061107c576040516302e7c60160e31b815260040160405180910390fd5b60006110a13386848151811061109457611094613ae1565b60200260200101516112c0565b905060006110c8338785815181106110bb576110bb613ae1565b6020026020010151612114565b9050806001600160601b03168260a001516001600160601b03161080156110f157508160e00151155b156111865760a08201516111058183613b47565b61110f9086613b67565b3360009081526009602052604090208851919650839189908790811061113757611137613ae1565b60200260200101518154811061114f5761114f613ae1565b9060005260206000209060030201600101600c6101000a8154816001600160601b0302191690836001600160601b03160217905550505b505060010161103a565b50806001600160601b03166000036111bb576040516373380d9960e01b815260040160405180910390fd5b806008600c8282829054906101000a90046001600160601b03166111df9190613b67565b82546001600160601b039182166101009390930a92830291909202199091161790555060065460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb906112349033908590600401613bd5565b6020604051808303816000875af1158015611253573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112779190613bb3565b50336001600160a01b03167fcf3dc675b372b9480b8de78cb48a2d2fe2aae7ade838c6d9025ab9c0e1b45a6b84836040516112b3929190613bf7565b60405180910390a2505050565b6112c8613575565b6001600160a01b03831660009081526009602052604090208054839081106112f2576112f2613ae1565b600091825260209091206040805161010081019091526003909202018054829060ff166004811115611326576113266135f4565b6004811115611337576113376135f4565b81528154610100810464ffffffffff9081166020840152600160301b8204166040830152600160581b90046001600160601b03908116606083015260018301548082166080840152600160601b90819004821660a084015260029093015490811660c08301529190910460ff16151560e0909101529392505050565b60008060008060006113c486613032565b905060005b8181101561150d576001600160a01b03871660009081526009602052604081208054839081106113fb576113fb613ae1565b600091825260209091206040805161010081019091526003909202018054829060ff16600481111561142f5761142f6135f4565b6004811115611440576114406135f4565b81528154610100810464ffffffffff9081166020840152600160301b8204166040830152600160581b90046001600160601b0390811660608084019190915260018401548083166080850152600160601b90819004831660a085015260029094015491821660c084015292900460ff16151560e0909101528101519091506114c89088613b67565b96508060800151866114da9190613b67565b95508060a00151856114ec9190613b67565b94506114f88883612114565b6115029085613b67565b9350506001016113c9565b50509193509193565b60008060008060008061152833613032565b9050808751111561154f576040516001621398b960e31b0319815260040160405180910390fd5b60005b8751811015611781578188828151811061156e5761156e613ae1565b602002602001015110611594576040516302e7c60160e31b815260040160405180910390fd5b60006115ac338a848151811061109457611094613ae1565b9050806040015164ffffffffff164210156115da57604051632968c44760e21b815260040160405180910390fd5b8060e00151156115fd57604051635e72b67160e01b815260040160405180910390fd5b606081015161160c9089613b67565b975080608001518761161e9190613b67565b96508060a0015181608001516116349190613b47565b61163e9087613b67565b95508060a00151816060015182608001516116599190613b47565b6116639190613b47565b61166d9085613b67565b93508060c001518561167f9190613b67565b9450806060015181608001516116959190613b47565b3360009081526009602052604090208a518b90859081106116b8576116b8613ae1565b6020026020010151815481106116d0576116d0613ae1565b600091825260208083206001600390930201820180546001600160601b0395909516600160601b026bffffffffffffffffffffffff60601b19909516949094179093553382526009909252604090208a518b908590811061173357611733613ae1565b60200260200101518154811061174b5761174b613ae1565b600091825260209091206002600390920201018054911515600160601b0260ff60601b1990921691909117905550600101611552565b50816008600c8282829054906101000a90046001600160601b03166117a69190613b67565b92506101000a8154816001600160601b0302191690836001600160601b031602179055506117dd33846001600160601b031661336c565b60065460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9061180f9033908890600401613bd5565b6020604051808303816000875af115801561182e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118529190613bb3565b50336001600160a01b03167f3e6e14ff492fd2081343250baa4cbaa1950e574db4143f8ec0b33736b6ed2542888888886040516118929493929190613c22565b60405180910390a250505050505050565b6005546001600160a01b031633146118ce576040516330cd747160e01b815260040160405180910390fd5b600780546001600160a01b0319166001600160a01b0383169081179091556040517f6a94f93d0f80241b5d6e8b868e1df78fc5f8024f40f9b79643a6d62bfdf6424290600090a250565b6001600160a01b038216600090815260096020526040812080548291908490811061194557611945613ae1565b600091825260209091206040805161010081019091526003909202018054829060ff166004811115611979576119796135f4565b600481111561198a5761198a6135f4565b81528154610100810464ffffffffff9081166020840152600160301b82048116604080850191909152600160581b9092046001600160601b03908116606085015260018501548082166080860152600160601b90819004821660a086015260029095015490811660c08501529390930460ff16151560e0909201919091528201519192501642101580611a1e57508060e001515b15611a2c5760009150610ea6565b80602001518160400151611a409190613c5e565b611a549064ffffffffff16620186a0613c7c565b42826040015164ffffffffff16611a6b9190613c93565b6060830151600654611a93916001600160601b031690600160a01b900463ffffffff16613c7c565b611a9d9190613c7c565b611aa79190613ca6565b949350505050565b6006546040516370a0823160e01b81523360048201526001600160601b038416916001600160a01b0316906370a0823190602401602060405180830381865afa158015611b00573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b249190613b9a565b1015611b4357604051631d00495b60e31b815260040160405180910390fd5b600a6000826004811115611b5957611b596135f4565b60ff16815260208101919091526040016000908120546001600160601b03169003611b97576040516365fce3a760e11b815260040160405180910390fd5b6000611ba3838361304d565b3360009081526009602090815260408220805460018181018355918452919092208351600390920201805493945084939092839160ff191690836004811115611bee57611bee6135f4565b021790555060208201518154604084015160608501516affffffffffffffffffff001990921661010064ffffffffff948516026affffffffff000000000000191617600160301b9390911692909202919091176bffffffffffffffffffffffff60581b1916600160581b6001600160601b0392831602178255608083015160018301805460a08601519284166001600160c01b031990911617600160601b928416830217905560c08401516002909301805460e0909501519383166cffffffffffffffffffffffffff19909516949094179215150291909117909155600780548592601491611ce6918591600160a01b900416613b67565b82546101009290920a6001600160601b038181021990931691831602179091553360008181526009602052604090205460c0850151909350611d289216613188565b6006546040516323b872dd60e01b81523360048201523060248201526001600160601b03861660448201526001600160a01b03909116906323b872dd906064016020604051808303816000875af1158015611d87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dab9190613bb3565b50337f1c83975eb7d62799fd03db85395e9949a70a760b1e5d2be50180bd95efb2cd9f611dd9600184613c93565b8685608001518660400151886004811115611df657611df66135f4565b604080519586526001600160601b039485166020870152929093168483015264ffffffffff16606084015260ff9091166080830152519081900360a00190a250505050565b6060600480546108b590613af7565b6005546001600160a01b03163314611e75576040516330cd747160e01b815260040160405180910390fd5b6001816001600160601b03161015611ea057604051631f2a200560e01b815260040160405180910390fd5b80600a6000846004811115611eb757611eb76135f4565b60ff168152602081019190915260400160002080546bffffffffffffffffffffffff19166001600160601b03929092169190911790557f578b86c872c0807eedb1a1cb5ffd80b43c061f0b0c8b305db3e5f0a5737fb1fa826004811115611f2057611f206135f4565b6040805160ff90921682526001600160601b0384166020830152015b60405180910390a15050565b60606000611f5583613032565b905060005b81811015612082576001600160a01b0384166000908152600960205260408120805483908110611f8c57611f8c613ae1565b600091825260209091206040805161010081019091526003909202018054829060ff166004811115611fc057611fc06135f4565b6004811115611fd157611fd16135f4565b81528154610100810464ffffffffff9081166020840152600160301b8204166040830152600160581b90046001600160601b03908116606083015260018301548082166080840152600160601b90819004821660a084015260029093015490811660c08301529190910460ff16151560e0918201528101519091501580156120635750806040015164ffffffffff1642105b1561207957835160010180855260200284018290525b50600101611f5a565b5050919050565b600033816120978286612975565b9050838110156120fc5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084015b60405180910390fd5b6121098286868403613247565b506001949350505050565b6001600160a01b038216600090815260096020526040812080548291908490811061214157612141613ae1565b600091825260209091206040805161010081019091526003909202018054829060ff166004811115612175576121756135f4565b6004811115612186576121866135f4565b81528154610100810464ffffffffff9081166020840152600160301b8204166040830152600160581b90046001600160601b03908116606083015260018301548082166080840152600160601b90819004821660a084015260029093015490811660c08301529190910460ff16151560e0918201528101519091501561220f5760009150610ea6565b806040015164ffffffffff16421061223c57806060015181608001516122359190613b47565b9150610ea6565b806020015181604001516122509190613c5e565b64ffffffffff16816020015164ffffffffff164261226e9190613c93565b826060015183608001516122829190613b47565b6001600160601b0316611a9d9190613c7c565b60006122a083613032565b825111156122c4576040516001621398b960e31b0319815260040160405180910390fd5b60005b8251811015610ea6576001600160a01b038416600090815260096020526040812084518590849081106122fc576122fc613ae1565b60200260200101518154811061231457612314613ae1565b600091825260209091206040805161010081019091526003909202018054829060ff166004811115612348576123486135f4565b6004811115612359576123596135f4565b81528154610100810464ffffffffff9081166020840152600160301b8204166040830152600160581b90046001600160601b0390811660608084019190915260018401548083166080850152600160601b90819004831660a085015260029094015491821660c084015292900460ff16151560e0909101528101519091506123e19084613b67565b9250506001016122c7565b6001600160a01b038216600090815260096020526040812080548390811061241657612416613ae1565b6000918252602090912060039091020154600160301b900464ffffffffff164210610d4b5750600192915050565b6009602052816000526040600020818154811061246057600080fd5b600091825260209091206003909102018054600182015460029092015460ff808316955064ffffffffff610100840481169550600160301b840416936001600160601b03600160581b90940484169381811693600160601b928390048216939181169290041688565b60006124d483613032565b825111156124f8576040516001621398b960e31b0319815260040160405180910390fd5b60005b8251811015610ea6576001600160a01b0384166000908152600960205260408120845185908490811061253057612530613ae1565b60200260200101518154811061254857612548613ae1565b600091825260209091206040805161010081019091526003909202018054829060ff16600481111561257c5761257c6135f4565b600481111561258d5761258d6135f4565b81528154610100810464ffffffffff9081166020840152600160301b8204166040830152600160581b90046001600160601b03908116606083015260018301548082166080840152600160601b90819004821660a084015260029093015490811660c08301529190910460ff16151560e0918201528101519091501561261f57612618600084613b67565b92506126bf565b806040015164ffffffffff16421061264f57806060015181608001516126459190613b47565b6126189084613b67565b806020015181604001516126639190613c5e565b64ffffffffff16816020015164ffffffffff16426126819190613c93565b826060015183608001516126959190613b47565b6001600160601b03166126a89190613c7c565b6126b29190613ca6565b6126bc9084613b67565b92505b506001016124fb565b6005546001600160a01b031633146126f3576040516330cd747160e01b815260040160405180910390fd5b60018163ffffffff16101561271b57604051631f2a200560e01b815260040160405180910390fd5b6006805463ffffffff60a01b1916600160a01b63ffffffff8416908102919091179091556040519081527f714f865fe90480bc6f60d9b15d54b5a3c34526bd214657b30eacbecb2f770b4c9060200160405180910390a150565b600061278083613032565b825111156127a4576040516001621398b960e31b0319815260040160405180910390fd5b60005b8251811015610ea6576001600160a01b038416600090815260096020526040812084518590849081106127dc576127dc613ae1565b6020026020010151815481106127f4576127f4613ae1565b600091825260209091206040805161010081019091526003909202018054829060ff166004811115612828576128286135f4565b6004811115612839576128396135f4565b81528154610100810464ffffffffff9081166020840152600160301b82048116604080850191909152600160581b9092046001600160601b03908116606085015260018501548082166080860152600160601b90819004821660a086015260029095015490811660c08501529390930460ff16151560e09092019190915282015191925016421015806128cd57508060e001515b156128e4576128dd600084613b67565b925061296c565b806020015181604001516128f89190613c5e565b61290c9064ffffffffff16620186a0613c7c565b42826040015164ffffffffff166129239190613c93565b606083015160065461294b916001600160601b031690600160a01b900463ffffffff16613c7c565b6129559190613c7c565b61295f9190613ca6565b6129699084613b67565b92505b506001016127a7565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60006129ab33613032565b905080825111156129d2576040516001621398b960e31b0319815260040160405180910390fd5b60008060008060005b8651811015612c2757858782815181106129f7576129f7613ae1565b602002602001015110612a1d576040516302e7c60160e31b815260040160405180910390fd5b6000612a353389848151811061109457611094613ae1565b9050806040015164ffffffffff164210612a625760405163d3436bcb60e01b815260040160405180910390fd5b8060e0015115612a8557604051635e72b67160e01b815260040160405180910390fd5b6000612a9d338a85815181106110bb576110bb613ae1565b90506000612ac4338b8681518110612ab757612ab7613ae1565b6020026020010151611918565b90508260a0015182612ad69190613b47565b612ae09089613b67565b97508260a0015182612af29190613b47565b818460600151612b029190613b47565b612b0c9190613b67565b612b169088613b67565b9650612b228187613b67565b95508260c0015185612b349190613b67565b3360009081526009602052604090208b5191965083918c9087908110612b5c57612b5c613ae1565b602002602001015181548110612b7457612b74613ae1565b600091825260208083206001600390930201820180546001600160601b0395909516600160601b026bffffffffffffffffffffffff60601b19909516949094179093553382526009909252604090208b518c9087908110612bd757612bd7613ae1565b602002602001015181548110612bef57612bef613ae1565b600091825260209091206002600390920201018054911515600160601b0260ff60601b199092169190911790555050506001016129db565b50836008600c8282829054906101000a90046001600160601b0316612c4c9190613b67565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555081600860008282829054906101000a90046001600160601b0316612c949190613b67565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550612ccb33826001600160601b031661336c565b60065460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb90612cfd9033908790600401613bd5565b6020604051808303816000875af1158015612d1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d409190613bb3565b5060065460075460405163a9059cbb60e01b81526001600160a01b039283169263a9059cbb92612d77929116908690600401613bd5565b6020604051808303816000875af1158015612d96573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dba9190613bb3565b50336001600160a01b03167fd8a0f675e5c0d97fc6b4eace3d3f8f0d844d7acd23417c1d76d8b4fc9e616e43878585604051610d1393929190613cc8565b6005546001600160a01b03163314612e23576040516330cd747160e01b815260040160405180910390fd5b60018163ffffffff161015612e4b57604051631f2a200560e01b815260040160405180910390fd5b80600b6000846004811115612e6257612e626135f4565b60ff1681526020810191909152604001600020805463ffffffff191663ffffffff929092169190911790557fabeb6b6d39f1fc7eb48ffdc5f1f76e68c7d4f81d9dbff3295aaa06e4779015c4826004811115612ec057612ec06135f4565b6040805160ff909216825263ffffffff8416602083015201611f3c565b6000612ee883613032565b82511115612f0c576040516001621398b960e31b0319815260040160405180910390fd5b60005b8251811015610ea6576001600160a01b03841660009081526009602052604081208451859084908110612f4457612f44613ae1565b602002602001015181548110612f5c57612f5c613ae1565b600091825260209091206040805161010081019091526003909202018054829060ff166004811115612f9057612f906135f4565b6004811115612fa157612fa16135f4565b8152815464ffffffffff610100820481166020840152600160301b82041660408301526001600160601b03600160581b9091048116606083015260018301548082166080840152600160601b90819004821660a08085019190915260029094015491821660c084015260ff910416151560e0909101528101519091506130279084613b67565b925050600101612f0f565b6001600160a01b031660009081526009602052604090205490565b613055613575565b64ffffffffff421660208201526001600160601b0383166060820181905268056bc75e2d63100000600a6000856004811115613093576130936135f4565b60ff1681526020810191909152604001600020546130be906001600160601b03908116908716613c7c565b6130c89190613ca6565b6130d29190613b87565b6001600160601b03166080820152808260048111156130f3576130f36135f4565b90816004811115613106576131066135f4565b90525061311282613496565b64ffffffffff16604082015260608101516103e8906001600160601b0316600b6000856004811115613146576131466135f4565b60ff16815260208101919091526040016000205461316a919063ffffffff16613c7c565b6131749190613ca6565b6001600160601b031660c082015292915050565b6001600160a01b0382166131de5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016120f3565b80600260008282546131f09190613b87565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6001600160a01b0383166132a95760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016120f3565b6001600160a01b03821661330a5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016120f3565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6001600160a01b0382166133cc5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b60648201526084016120f3565b6001600160a01b038216600090815260208190526040902054818110156134405760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b60648201526084016120f3565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910161335f565b6000808260048111156134ab576134ab6135f4565b036134bd57610d4b4262278d00613b87565b60018260048111156134d1576134d16135f4565b036134e357610d4b426276a700613b87565b60028260048111156134f7576134f76135f4565b0361350957610d4b4262ed4e00613b87565b600382600481111561351d5761351d6135f4565b0361353057610d4b426301e13380613b87565b6004826004811115613544576135446135f4565b0361355757610d4b426303c26700613b87565b6040516365fce3a760e11b815260040160405180910390fd5b919050565b604080516101008101909152806000815260006020820181905260408201819052606082018190526080820181905260a0820181905260c0820181905260e09091015290565b80356001600160a01b038116811461357057600080fd5b6000602082840312156135e457600080fd5b6135ed826135bb565b9392505050565b634e487b7160e01b600052602160045260246000fd5b6005811061362857634e487b7160e01b600052602160045260246000fd5b9052565b61363782825161360a565b602081015164ffffffffff8082166020850152806040840151166040850152505060608101516001600160601b0380821660608501528060808401511660808501528060a08401511660a08501528060c08401511660c0850152505060e0810151151560e08301525050565b6020808252825182820181905260009190848201906040850190845b818110156136e6576136d283855161362c565b9284019261010092909201916001016136bf565b50909695505050505050565b600060208083528351808285015260005b8181101561371f57858101830151858201604001528201613703565b506000604082860101526040601f19601f8301168501019250505092915050565b6000806040838503121561375357600080fd5b61375c836135bb565b946020939093013593505050565b80356005811061357057600080fd5b6000806040838503121561378c57600080fd5b8235915061379c6020840161376a565b90509250929050565b6000806000606084860312156137ba57600080fd5b6137c3846135bb565b92506137d1602085016135bb565b9150604084013590509250925092565b6000602082840312156137f357600080fd5b813560ff811681146135ed57600080fd5b634e487b7160e01b600052604160045260246000fd5b600082601f83011261382b57600080fd5b8135602067ffffffffffffffff8083111561384857613848613804565b8260051b604051601f19603f8301168101818110848211171561386d5761386d613804565b60405293845285810183019383810192508785111561388b57600080fd5b83870191505b848210156138aa57813583529183019190830190613891565b979650505050505050565b600080604083850312156138c857600080fd5b6138d1836135bb565b9150602083013567ffffffffffffffff8111156138ed57600080fd5b6138f98582860161381a565b9150509250929050565b60006020828403121561391557600080fd5b813567ffffffffffffffff81111561392c57600080fd5b611aa78482850161381a565b6101008101610d4b828461362c565b80356001600160601b038116811461357057600080fd5b6000806040838503121561397157600080fd5b61397a83613947565b915061379c6020840161376a565b6000806040838503121561399b57600080fd5b6139a48361376a565b915061379c60208401613947565b600081518084526020808501945080840160005b838110156139e2578151875295820195908201906001016139c6565b509495945050505050565b6020815260006135ed60208301846139b2565b6101008101613a0f828b61360a565b64ffffffffff98891660208301529690971660408801526001600160601b039485166060880152928416608087015290831660a086015290911660c0840152151560e090920191909152919050565b803563ffffffff8116811461357057600080fd5b600060208284031215613a8457600080fd5b6135ed82613a5e565b60008060408385031215613aa057600080fd5b613aa9836135bb565b915061379c602084016135bb565b60008060408385031215613aca57600080fd5b613ad38361376a565b915061379c60208401613a5e565b634e487b7160e01b600052603260045260246000fd5b600181811c90821680613b0b57607f821691505b602082108103613b2b57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b6001600160601b03828116828216039080821115610ea657610ea6613b31565b6001600160601b03818116838216019080821115610ea657610ea6613b31565b80820180821115610d4b57610d4b613b31565b600060208284031215613bac57600080fd5b5051919050565b600060208284031215613bc557600080fd5b815180151581146135ed57600080fd5b6001600160a01b039290921682526001600160601b0316602082015260400190565b604081526000613c0a60408301856139b2565b90506001600160601b03831660208301529392505050565b608081526000613c3560808301876139b2565b6001600160601b0395861660208401529385166040830152509216606090920191909152919050565b64ffffffffff828116828216039080821115610ea657610ea6613b31565b8082028115828204841417610d4b57610d4b613b31565b81810381811115610d4b57610d4b613b31565b600082613cc357634e487b7160e01b600052601260045260246000fd5b500490565b606081526000613cdb60608301866139b2565b6001600160601b039485166020840152929093166040909101529291505056fea2646970667358221220ec60376bf8c26f8d1e41b407803a3afe47ab4354ed53fa1c2bf7c0101fb4800364736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000009343e24716659a3551eb10aff9472a2dcad5db2d
-----Decoded View---------------
Arg [0] : _token (address): 0x9343e24716659A3551eB10Aff9472A2dcAD5Db2d
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000009343e24716659a3551eb10aff9472a2dcad5db2d
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.