Source Code
Overview
APE Balance
0 APE
More Info
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60406080 | 10515555 | 36 days ago | IN | 0 APE | 0.00002844 |
Latest 1 internal transaction
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
10515555 | 36 days ago | Contract Creation | 0 APE |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
DividendApeToken
Compiler Version
v0.8.24+commit.e11b9ed9
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.24; import {ERC20Burnable, ERC20} from "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol"; import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; import {IUniswapV2Factory} from "@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol"; import {IUniswapV2Router02} from "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol"; import {IUniswapV2Pair} from "@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol"; import {DividendTracker} from "../dividend/DividendTracker.sol"; import {IDividendApeToken} from "./IDividendApeToken.sol"; /** * @title Official gemlabs dividend APE token contract * @author The gemlabs crew | https://www.gemlabs.wtf | X: https://twitter.com/gemlabs_wtf | Telegram: https://t.me/gemlabs_wtf */ contract DividendApeToken is ERC20Burnable, Ownable, IDividendApeToken, ReentrancyGuard { uint256 private constant DENOMINATOR = 100_00; uint256 private constant GAS_FOR_PROCESSING = 500_000; address public constant PINK_LOCK_CONTRACT = 0xdD6E31A046b828CbBAfb939C2a394629aff8BBdC; // Maybe remove or adjust this ? IUniswapV2Router02 public uniswapV2Router; IUniswapV2Pair public uniswapV2Pair; DividendTracker public dividendTracker; uint256 public swapTokensAtAmount; address public deployerWallet; address public teamWallet; uint256 public dividendsFee; uint256 public teamFee; uint256 public burnFee; mapping(address => bool) public _isExcludedFromFees; mapping(address => bool) public automatedMarketMakerPairs; bool private swapping; constructor( string memory _name, string memory _symbol, uint256 _initialSupply, address _router, uint256 _minimumTokenBalanceForDividendsPct, address _teamWallet, uint256 _teamFee, uint256 _dividendsFee, uint256 _burnFee ) ERC20(_name, _symbol) Ownable(msg.sender) { deployerWallet = msg.sender; teamWallet = _teamWallet; dividendsFee = _dividendsFee; teamFee = _teamFee; burnFee = _burnFee; uint256 totalFee = dividendsFee + teamFee + burnFee; if (totalFee > 10000) { revert InvalidFee(totalFee); } swapTokensAtAmount = (_initialSupply) / (DENOMINATOR * 100); // 0.0001% dividendTracker = new DividendTracker((_initialSupply * _minimumTokenBalanceForDividendsPct) / DENOMINATOR); // uniswapV2Router = IUniswapV2Router02(_router); // uniswapV2Pair = IUniswapV2Pair( // IUniswapV2Factory(uniswapV2Router.factory()).createPair(address(this), uniswapV2Router.WETH()) // ); // _setAutomatedMarketMakerPair(address(uniswapV2Pair), true); // // exclude from receiving dividends // dividendTracker.excludeFromDividends(address(dividendTracker)); // dividendTracker.excludeFromDividends(address(this)); // dividendTracker.excludeFromDividends(teamWallet); // dividendTracker.excludeFromDividends(msg.sender); // dividendTracker.excludeFromDividends(address(0xdead)); // dividendTracker.excludeFromDividends(address(0x0000000000000000000000000000000000000002)); // dividendTracker.excludeFromDividends(address(0)); // dividendTracker.excludeFromDividends(address(uniswapV2Router)); // dividendTracker.excludeFromDividends(address(uniswapV2Pair)); // dividendTracker.excludeFromDividends(PINK_LOCK_CONTRACT); // // exclude from paying fees or having max transaction amount // _isExcludedFromFees[msg.sender] = true; // _isExcludedFromFees[teamWallet] = true; // _isExcludedFromFees[address(this)] = true; // _isExcludedFromFees[PINK_LOCK_CONTRACT] = true; // _mint(msg.sender, _initialSupply); } receive() external payable {} /** * @notice Excludes or includes an account from fees. * @param account The address of the account to be excluded or included. * @param excluded A boolean indicating whether the account is to be excluded (true) or included (false) in fees. * @dev Only callable by the owner. */ function excludeFromFees(address account, bool excluded) external onlyOwner { _isExcludedFromFees[account] = excluded; emit ExcludeFromFees(account, excluded); } /** * @notice Sets the team wallet address. * @param wallet The address of the new team wallet. * @dev Only callable by the owner. */ function setTeamWallet(address payable wallet) external onlyOwner { teamWallet = wallet; } /** * @notice Sets the team fee. * @param value The new value for the team fee. * @dev Only callable by the owner. */ function setTeamFee(uint256 value) external onlyOwner { if (value > 10000) { revert InvalidFee(value); } teamFee = value; } /** * @notice Sets the dividends fee. * @param value The new value for the dividends fee. * @dev Only callable by the owner. */ function setDividendsFee(uint256 value) external onlyOwner { if (value > 10000) { revert InvalidFee(value); } dividendsFee = value; } /** * @notice Sets the burn fee. * @param value The new value for the burn fee. * @dev Only callable by the owner. */ function setBurnFee(uint256 value) external onlyOwner { if (value > 10000) { revert InvalidFee(value); } burnFee = value; } /** * @notice Sets or unsets an address as an automated market maker pair. * @param pair The address of the pair to be set or unset. * @param value A boolean indicating whether to set (true) or unset (false) the pair as an automated market maker. */ function setAutomatedMarketMakerPair(address pair, bool value) external { if (msg.sender != deployerWallet) { return; } if (pair == address(uniswapV2Pair)) { revert CannotRemoveUniswapPair(pair); } _setAutomatedMarketMakerPair(pair, value); } function _setAutomatedMarketMakerPair(address pair, bool value) private { if (automatedMarketMakerPairs[pair] == value) { revert PairAlreadySetToValue(pair, value); } automatedMarketMakerPairs[pair] = value; if (value) { dividendTracker.excludeFromDividends(pair); } emit SetAutomatedMarketMakerPair(pair, value); } /** * @notice Updates the claim wait time for dividends. * @param claimWait The new claim wait time in seconds. * @dev Calls the updateClaimWait function on the dividendTracker to update the claim wait time. * Only callable by the owner. */ function updateClaimWait(uint256 claimWait) external onlyOwner { dividendTracker.updateClaimWait(claimWait); } /** * @notice Checks if an account is excluded from fees. * @param account The address of the account to check. * @return A boolean indicating whether the account is excluded from fees. */ function isExcludedFromFees(address account) external view returns (bool) { return _isExcludedFromFees[account]; } /** * @notice Gets the amount of withdrawable dividends for an account. * @param account The address of the account to check. * @return The amount of withdrawable dividends for the specified account. * @dev Calls the withdrawableDividendOf function on the dividendTracker to get the amount of withdrawable dividends. */ function withdrawableDividendOf(address account) external view returns (uint256) { return dividendTracker.withdrawableDividendOf(account); } /** * @notice Excludes an account from receiving dividends. * @param account The address of the account to exclude. * @dev Calls the excludeFromDividends function on the dividendTracker to exclude the specified account from receiving dividends. * Only callable by the owner. */ function excludeFromDividends(address account) external onlyOwner { dividendTracker.excludeFromDividends(account); } /** * @notice Processes the dividend tracker with a specified amount of gas. * @param gas The amount of gas to use for processing. * @dev Calls the process function on the dividendTracker with the specified gas. */ function processDividendTracker(uint256 gas) external { (uint256 iterations, uint256 claims, uint256 lastProcessedIndex) = dividendTracker.process(gas); emit ProcessedDividendTracker(iterations, claims, lastProcessedIndex, false, gas, tx.origin); } /** * @notice Claims dividends for the caller. * @dev Calls the processAccount function on the dividendTracker for the caller. */ function claim() external { dividendTracker.processAccount(payable(msg.sender), false); } function _update(address from, address to, uint256 amount) internal virtual override { if (amount == 0) { super._update(from, to, 0); return; } uint256 contractTokenBalance = balanceOf(address(this)); bool canSwap = contractTokenBalance >= swapTokensAtAmount; uint256 totalFees = dividendsFee + teamFee + burnFee; if (canSwap && !swapping && !automatedMarketMakerPairs[from] && from != owner() && to != owner()) { swapping = true; uint256 tokensForNativeSwap = contractTokenBalance; swapTokensForNative(tokensForNativeSwap); uint256 ethBalance = address(this).balance; if (totalFees > 0) { uint256 totalETHForFees = ethBalance; uint256 rewardETH = ethBalance; if (teamFee > 0) { uint256 teamETH = (totalETHForFees * teamFee) / totalFees; _safeTransferETH(teamWallet, teamETH); rewardETH -= teamETH; } if (burnFee > 0) { uint256 burnETH = (totalETHForFees * burnFee) / totalFees; _burn(address(this), burnETH); rewardETH -= burnETH; } if (rewardETH > 0) { sendAndDistributeDividends(rewardETH); } } swapping = false; } bool takeFee = !swapping; // Skip the fee for normal transfers (not buy or sell) if (!automatedMarketMakerPairs[from] && !automatedMarketMakerPairs[to]) { takeFee = false; } if (_isExcludedFromFees[from] || _isExcludedFromFees[to]) { takeFee = false; } if (takeFee) { uint256 fees = (amount * totalFees) / 10000; super._update(from, address(this), fees); amount = amount - fees; } super._update(from, to, amount); if (!swapping) { uint256 gas = GAS_FOR_PROCESSING; try dividendTracker.process(gas) returns (uint256 iterations, uint256 claims, uint256 lastProcessedIndex) { emit ProcessedDividendTracker(iterations, claims, lastProcessedIndex, true, gas, tx.origin); } catch {} } } function swapTokensForNative(uint256 tokenAmount) private { address[] memory path = new address[](2); path[0] = address(this); path[1] = uniswapV2Router.WETH(); _approve(address(this), address(uniswapV2Router), tokenAmount); uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens( tokenAmount, 0, // accept any amount of ETH path, address(this), block.timestamp + 300 ); } function sendAndDistributeDividends(uint256 ethAmount) private { bool success = _safeTransferETH(payable(address(dividendTracker)), ethAmount); if (success) { dividendTracker.distributeDividends(ethAmount); emit SendDividends(ethAmount); } } function _safeTransferETH(address to, uint256 value) private returns (bool) { (bool success, ) = to.call{value: value, gas: 30_000}(new bytes(0)); return success; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; import {Context} from "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is set to the address provided by the deployer. This can * later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol) pragma solidity ^0.8.20; /** * @dev Standard ERC20 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens. */ interface IERC20Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC20InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC20InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers. * @param spender Address that may be allowed to operate on tokens without being their owner. * @param allowance Amount of tokens a `spender` is allowed to operate with. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC20InvalidApprover(address approver); /** * @dev Indicates a failure with the `spender` to be approved. Used in approvals. * @param spender Address that may be allowed to operate on tokens without being their owner. */ error ERC20InvalidSpender(address spender); } /** * @dev Standard ERC721 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens. */ interface IERC721Errors { /** * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20. * Used in balance queries. * @param owner Address of the current owner of a token. */ error ERC721InvalidOwner(address owner); /** * @dev Indicates a `tokenId` whose `owner` is the zero address. * @param tokenId Identifier number of a token. */ error ERC721NonexistentToken(uint256 tokenId); /** * @dev Indicates an error related to the ownership over a particular token. Used in transfers. * @param sender Address whose tokens are being transferred. * @param tokenId Identifier number of a token. * @param owner Address of the current owner of a token. */ error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC721InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC721InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param tokenId Identifier number of a token. */ error ERC721InsufficientApproval(address operator, uint256 tokenId); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC721InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC721InvalidOperator(address operator); } /** * @dev Standard ERC1155 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens. */ interface IERC1155Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. * @param tokenId Identifier number of a token. */ error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC1155InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC1155InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param owner Address of the current owner of a token. */ error ERC1155MissingApprovalForAll(address operator, address owner); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC1155InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC1155InvalidOperator(address operator); /** * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation. * Used in batch transfers. * @param idsLength Length of the array of token identifiers * @param valuesLength Length of the array of token amounts */ error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "./IERC20.sol"; import {IERC20Metadata} from "./extensions/IERC20Metadata.sol"; import {Context} from "../../utils/Context.sol"; import {IERC20Errors} from "../../interfaces/draft-IERC6093.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}. * * 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]. * * The default value of {decimals} is 18. To change this, you should override * this function so it returns a different value. * * 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. */ abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors { mapping(address account => uint256) private _balances; mapping(address account => mapping(address spender => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * 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 returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual 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 default value returned by this function, unless * it's 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 returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual 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 `value`. */ function transfer(address to, uint256 value) public virtual returns (bool) { address owner = _msgSender(); _transfer(owner, to, value); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `value` 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 value) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, value); 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 `value`. * - the caller must have allowance for ``from``'s tokens of at least * `value`. */ function transferFrom(address from, address to, uint256 value) public virtual returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, value); _transfer(from, to, value); return true; } /** * @dev Moves a `value` 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. * * NOTE: This function is not virtual, {_update} should be overridden instead. */ function _transfer(address from, address to, uint256 value) internal { if (from == address(0)) { revert ERC20InvalidSender(address(0)); } if (to == address(0)) { revert ERC20InvalidReceiver(address(0)); } _update(from, to, value); } /** * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from` * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding * this function. * * Emits a {Transfer} event. */ function _update(address from, address to, uint256 value) internal virtual { if (from == address(0)) { // Overflow check required: The rest of the code assumes that totalSupply never overflows _totalSupply += value; } else { uint256 fromBalance = _balances[from]; if (fromBalance < value) { revert ERC20InsufficientBalance(from, fromBalance, value); } unchecked { // Overflow not possible: value <= fromBalance <= totalSupply. _balances[from] = fromBalance - value; } } if (to == address(0)) { unchecked { // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply. _totalSupply -= value; } } else { unchecked { // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256. _balances[to] += value; } } emit Transfer(from, to, value); } /** * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0). * Relies on the `_update` mechanism * * Emits a {Transfer} event with `from` set to the zero address. * * NOTE: This function is not virtual, {_update} should be overridden instead. */ function _mint(address account, uint256 value) internal { if (account == address(0)) { revert ERC20InvalidReceiver(address(0)); } _update(address(0), account, value); } /** * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply. * Relies on the `_update` mechanism. * * Emits a {Transfer} event with `to` set to the zero address. * * NOTE: This function is not virtual, {_update} should be overridden instead */ function _burn(address account, uint256 value) internal { if (account == address(0)) { revert ERC20InvalidSender(address(0)); } _update(account, address(0), value); } /** * @dev Sets `value` 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. * * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument. */ function _approve(address owner, address spender, uint256 value) internal { _approve(owner, spender, value, true); } /** * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event. * * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any * `Approval` event during `transferFrom` operations. * * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to * true using the following override: * ``` * function _approve(address owner, address spender, uint256 value, bool) internal virtual override { * super._approve(owner, spender, value, true); * } * ``` * * Requirements are the same as {_approve}. */ function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual { if (owner == address(0)) { revert ERC20InvalidApprover(address(0)); } if (spender == address(0)) { revert ERC20InvalidSpender(address(0)); } _allowances[owner][spender] = value; if (emitEvent) { emit Approval(owner, spender, value); } } /** * @dev Updates `owner` s allowance for `spender` based on spent `value`. * * Does not update the allowance value in case of infinite allowance. * Revert if not enough allowance is available. * * Does not emit an {Approval} event. */ function _spendAllowance(address owner, address spender, uint256 value) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { if (currentAllowance < value) { revert ERC20InsufficientAllowance(spender, currentAllowance, value); } unchecked { _approve(owner, spender, currentAllowance - value, false); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20Burnable.sol) pragma solidity ^0.8.20; import {ERC20} from "../ERC20.sol"; import {Context} from "../../../utils/Context.sol"; /** * @dev Extension of {ERC20} that allows token holders to destroy both their own * tokens and those that they have an allowance for, in a way that can be * recognized off-chain (via event analysis). */ abstract contract ERC20Burnable is Context, ERC20 { /** * @dev Destroys a `value` amount of tokens from the caller. * * See {ERC20-_burn}. */ function burn(uint256 value) public virtual { _burn(_msgSender(), value); } /** * @dev Destroys a `value` amount of tokens from `account`, deducting from * the caller's allowance. * * See {ERC20-_burn} and {ERC20-allowance}. * * Requirements: * * - the caller must have allowance for ``accounts``'s tokens of at least * `value`. */ function burnFrom(address account, uint256 value) public virtual { _spendAllowance(account, _msgSender(), value); _burn(account, value); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.20; import {IERC20} from "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @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 value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens 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 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` 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 value) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @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; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/ReentrancyGuard.sol) pragma solidity ^0.8.20; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant NOT_ENTERED = 1; uint256 private constant ENTERED = 2; uint256 private _status; /** * @dev Unauthorized reentrant call. */ error ReentrancyGuardReentrantCall(); constructor() { _status = NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be NOT_ENTERED if (_status == ENTERED) { revert ReentrancyGuardReentrantCall(); } // Any calls to nonReentrant after this point will fail _status = ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == ENTERED; } }
pragma solidity >=0.5.0; interface IUniswapV2Factory { event PairCreated(address indexed token0, address indexed token1, address pair, uint); function feeTo() external view returns (address); function feeToSetter() external view returns (address); function getPair(address tokenA, address tokenB) external view returns (address pair); function allPairs(uint) external view returns (address pair); function allPairsLength() external view returns (uint); function createPair(address tokenA, address tokenB) external returns (address pair); function setFeeTo(address) external; function setFeeToSetter(address) external; }
pragma solidity >=0.5.0; interface IUniswapV2Pair { event Approval(address indexed owner, address indexed spender, uint value); event Transfer(address indexed from, address indexed to, uint value); function name() external pure returns (string memory); function symbol() external pure returns (string memory); function decimals() external pure returns (uint8); function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom(address from, address to, uint value) external returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint); function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; event Mint(address indexed sender, uint amount0, uint amount1); event Burn(address indexed sender, uint amount0, uint amount1, address indexed to); event Swap( address indexed sender, uint amount0In, uint amount1In, uint amount0Out, uint amount1Out, address indexed to ); event Sync(uint112 reserve0, uint112 reserve1); function MINIMUM_LIQUIDITY() external pure returns (uint); function factory() external view returns (address); function token0() external view returns (address); function token1() external view returns (address); function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); function price0CumulativeLast() external view returns (uint); function price1CumulativeLast() external view returns (uint); function kLast() external view returns (uint); function mint(address to) external returns (uint liquidity); function burn(address to) external returns (uint amount0, uint amount1); function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external; function skim(address to) external; function sync() external; function initialize(address, address) external; }
pragma solidity >=0.6.2; interface IUniswapV2Router01 { function factory() external pure returns (address); function WETH() external pure returns (address); function addLiquidity( address tokenA, address tokenB, uint amountADesired, uint amountBDesired, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB, uint liquidity); function addLiquidityETH( address token, uint amountTokenDesired, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external payable returns (uint amountToken, uint amountETH, uint liquidity); function removeLiquidity( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB); function removeLiquidityETH( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountToken, uint amountETH); function removeLiquidityWithPermit( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountA, uint amountB); function removeLiquidityETHWithPermit( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountToken, uint amountETH); function swapExactTokensForTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapTokensForExactTokens( uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut); function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn); function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts); function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts); }
pragma solidity >=0.6.2; import './IUniswapV2Router01.sol'; interface IUniswapV2Router02 is IUniswapV2Router01 { function removeLiquidityETHSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountETH); function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountETH); function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; function swapExactETHForTokensSupportingFeeOnTransferTokens( uint amountOutMin, address[] calldata path, address to, uint deadline ) external payable; function swapExactTokensForETHSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; }
// SPDX-License-Identifier: MIT // Factory: gemlabs pragma solidity ^0.8.24; interface IDividendApeToken { event ExcludeFromFees(address indexed account, bool isExcluded); event SetAutomatedMarketMakerPair(address indexed pair, bool indexed value); event SendDividends(uint256 amount); event ProcessedDividendTracker( uint256 iterations, uint256 claims, uint256 lastProcessedIndex, bool indexed automatic, uint256 gas, address indexed processor ); error InvalidFee(uint256 totalFee); error CannotRemoveUniswapPair(address pair); error PairAlreadySetToValue(address pair, bool value); function excludeFromFees(address account, bool excluded) external; function setTeamWallet(address payable wallet) external; function setDividendsFee(uint256 value) external; function setTeamFee(uint256 value) external; function setBurnFee(uint256 value) external; function setAutomatedMarketMakerPair(address pair, bool value) external; function updateClaimWait(uint256 claimWait) external; function isExcludedFromFees(address account) external view returns (bool); function withdrawableDividendOf(address account) external view returns (uint256); function excludeFromDividends(address account) external; function processDividendTracker(uint256 gas) external; function claim() external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.24; import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; import {IDividendTracker} from "./IDividendTracker.sol"; import {IterableMapping} from "./IterableMapping.sol"; /** * @title Official gemlabs dividend tracker contract * @author The gemlabs crew | https://www.gemlabs.wtf | X: https://twitter.com/gemlabs_wtf | Telegram: https://t.me/gemlabs_wtf */ contract DividendTracker is Ownable, IDividendTracker { uint256 private constant MAGNITUDE = 2 ** 128; using IterableMapping for IterableMapping.Map; IterableMapping.Map private tokenHoldersMap; uint256 public lastProcessedIndex; uint256 public totalSupply; uint256 public magnifiedDividendPerShare; uint256 public totalDividendsDistributed; uint256 public claimWait; uint256 public minimumTokenBalanceForDividends; mapping(address => bool) public excludedFromDividends; mapping(address => uint256) public lastClaimTimes; mapping(address => uint256) public tokenHolderBalances; mapping(address => int256) private magnifiedDividendCorrections; mapping(address => uint256) private withdrawnDividends; constructor(uint256 minimumTokenBalanceForDividends_) Ownable(msg.sender) { claimWait = 3600; minimumTokenBalanceForDividends = minimumTokenBalanceForDividends_; } /** * @notice Excludes an account from receiving dividends. * @param account The address of the account to be excluded. * @dev Only callable by the owner (Dividend Token). */ function excludeFromDividends(address account) external onlyOwner { excludedFromDividends[account] = true; _setBalance(account, 0); tokenHoldersMap.remove(account); emit ExcludeFromDividends(account); } /** * @notice Updates the waiting time between claims. * @param newClaimWait The new claim wait time in seconds. * @dev Only callable by the owner (Dividend Token). */ function updateClaimWait(uint256 newClaimWait) external onlyOwner { if (newClaimWait < 3600 || newClaimWait > 86400) { revert InvalidClaimWait(newClaimWait, 3600, 86400); } if (newClaimWait == claimWait) { revert ClaimWaitAlreadySet(newClaimWait); } claimWait = newClaimWait; emit ClaimWaitUpdated(newClaimWait, claimWait); } /** * @notice Retrieves the number of token holders. * @return uint256 The number of token holders. */ function getNumberOfTokenHolders() external view returns (uint256) { return tokenHoldersMap.keys.length; } /** * @notice Retrieves the token balance of a specific account. * @param account The address of the account. * @return uint256 The balance of the account. */ function getTokenHolderBalance(address account) external view returns (uint256) { return tokenHolderBalances[account]; } /** * @notice Retrieves account information for a specific account. * @param _account The address of the account. * @return account The address of the account. * @return index The index of the account in the token holders map. * @return iterationsUntilProcessed The number of iterations until the account is processed. * @return withdrawableDividends The amount of dividends that can be withdrawn by the account. * @return totalDividends The total amount of dividends earned by the account. * @return lastClaimTime The last time the account claimed dividends. * @return nextClaimTime The next time the account can claim dividends. * @return secondsUntilAutoClaimAvailable The number of seconds until the account can automatically claim dividends. */ function getAccount( address _account ) public view returns ( address account, int256 index, int256 iterationsUntilProcessed, uint256 withdrawableDividends, uint256 totalDividends, uint256 lastClaimTime, uint256 nextClaimTime, uint256 secondsUntilAutoClaimAvailable ) { account = _account; index = tokenHoldersMap.getIndexOfKey(account); iterationsUntilProcessed = -1; if (index >= 0) { if (uint256(index) > lastProcessedIndex) { iterationsUntilProcessed = index - int256(lastProcessedIndex); } else { uint256 processesUntilEndOfArray = tokenHoldersMap.keys.length > lastProcessedIndex ? tokenHoldersMap.keys.length - lastProcessedIndex : 0; iterationsUntilProcessed = index + int256(processesUntilEndOfArray); } } withdrawableDividends = withdrawableDividendOf(account); totalDividends = accumulativeDividendOf(account); lastClaimTime = lastClaimTimes[account]; nextClaimTime = lastClaimTime > 0 ? lastClaimTime + claimWait : 0; secondsUntilAutoClaimAvailable = nextClaimTime > block.timestamp ? nextClaimTime - block.timestamp : 0; } /** * @notice Retrieves account information at a specific index. * @param index The index in the token holders map. * @return (see getAccount) */ function getAccountAtIndex( uint256 index ) external view returns (address, int256, int256, uint256, uint256, uint256, uint256, uint256) { if (index >= tokenHoldersMap.size()) { return (address(0), -1, -1, 0, 0, 0, 0, 0); } address account = tokenHoldersMap.getKeyAtIndex(index); return getAccount(account); } function canAutoClaim(uint256 lastClaimTime) private view returns (bool) { if (lastClaimTime > block.timestamp) { return false; } return block.timestamp - lastClaimTime >= claimWait; } /** * @notice Processes dividend claims for token holders within the specified gas limit. * @param gas The maximum amount of gas to be used for processing. * @return (uint256, uint256, uint256) Returns the number of iterations, the number of claims, and the last processed index. */ function process(uint256 gas) public returns (uint256, uint256, uint256) { uint256 numberOfTokenHolders = tokenHoldersMap.keys.length; if (numberOfTokenHolders == 0) { return (0, 0, lastProcessedIndex); } uint256 _lastProcessedIndex = lastProcessedIndex; uint256 gasUsed = 0; uint256 gasLeft = gasleft(); uint256 iterations = 0; uint256 claims = 0; while (gasUsed < gas && iterations < numberOfTokenHolders) { _lastProcessedIndex++; if (_lastProcessedIndex >= tokenHoldersMap.keys.length) { _lastProcessedIndex = 0; } address account = tokenHoldersMap.keys[_lastProcessedIndex]; if (canAutoClaim(lastClaimTimes[account])) { if (processAccount(payable(account), true)) { claims++; } } iterations++; uint256 newGasLeft = gasleft(); if (gasLeft > newGasLeft) { gasUsed = gasUsed + gasLeft - newGasLeft; } gasLeft = newGasLeft; } lastProcessedIndex = _lastProcessedIndex; return (iterations, claims, lastProcessedIndex); } /** * @notice Processes the account for dividend withdrawal. * @param account The address of the account to process. * @param automatic A boolean indicating if the process was triggered automatically. * @return bool Returns true if dividends were withdrawn successfully, otherwise false. * @dev Only callable by the owner (Dividend Token). */ function processAccount(address payable account, bool automatic) public onlyOwner returns (bool) { uint256 amount = _withdrawDividendOfUser(account); if (amount > 0) { lastClaimTimes[account] = block.timestamp; emit Claim(account, amount, automatic); return true; } return false; } /** * @notice Distributes the specified amount of dividends to token holders. * @param amount The amount of dividends to distribute. * @dev Only callable by the owner (Dividend Token). */ function distributeDividends(uint256 amount) public onlyOwner { if (totalSupply == 0) { revert NoTotalSupply(); } if (amount > 0) { magnifiedDividendPerShare = magnifiedDividendPerShare + ((amount * MAGNITUDE) / totalSupply); emit DividendsDistributed(msg.sender, amount); totalDividendsDistributed = totalDividendsDistributed + amount; } } /** * @notice Withdraws the dividend for the caller. * @dev Calls the internal function to handle the dividend withdrawal process. */ function withdrawDividend() external { _withdrawDividendOfUser(payable(msg.sender)); } function _withdrawDividendOfUser(address payable user) internal returns (uint256) { uint256 _withdrawableDividend = withdrawableDividendOf(user); if (_withdrawableDividend > 0) { withdrawnDividends[user] = withdrawnDividends[user] + _withdrawableDividend; bool success = _safeTransferETH(user, _withdrawableDividend); emit DividendWithdrawn(user, _withdrawableDividend); if (!success) { withdrawnDividends[user] = withdrawnDividends[user] - _withdrawableDividend; return 0; } return _withdrawableDividend; } return 0; } /** * @notice View the amount of dividend in wei that an address can withdraw. * @param _owner The address of a token holder. * @return The amount of dividend in wei that `_owner` can withdraw. */ function withdrawableDividendOf(address _owner) public view returns (uint256) { return accumulativeDividendOf(_owner) - (withdrawnDividends[_owner]); } /** * @notice View the amount of dividend in wei that an address has withdrawn. * @param _owner The address of a token holder. * @return The amount of dividend in wei that `_owner` has withdrawn. */ function withdrawnDividendOf(address _owner) public view returns (uint256) { return withdrawnDividends[_owner]; } /** * @notice View the amount of dividend in wei that an address has earned in total. * @dev accumulativeDividendOf(_owner) = withdrawableDividendOf(_owner) + withdrawnDividendOf(_owner) * @param _owner The address of a token holder. * @return The amount of dividend in wei that `_owner` has earned in total. */ function accumulativeDividendOf(address _owner) public view returns (uint256) { uint256 balance = tokenHolderBalances[_owner]; int256 correction = magnifiedDividendCorrections[_owner]; int256 accumulatedDividend = int256(magnifiedDividendPerShare) * int256(balance) + correction; if (accumulatedDividend < 0) { return 0; } else { return uint256(accumulatedDividend) / MAGNITUDE; } } /** * @notice Gets the largest holder and their balance. * @return largestHolder The address of the largest holder. * @return largestBalance The balance of the largest holder. */ function getLargestHolder() external view returns (address largestHolder, uint256 largestBalance) { uint256 numberOfTokenHolders = tokenHoldersMap.keys.length; largestBalance = 0; for (uint256 i = 0; i < numberOfTokenHolders; i++) { address account = tokenHoldersMap.keys[i]; uint256 balance = tokenHolderBalances[account]; if (balance > largestBalance) { largestBalance = balance; largestHolder = account; } } return (largestHolder, largestBalance); } /** * @notice Set the balance of an account and update dividend eligibility. * @param account The address of the account. * @param newBalance The new balance for the account. * @dev Only callable by the owner (Dividend Token). */ function setBalance(address payable account, uint256 newBalance) external onlyOwner { if (excludedFromDividends[account]) { return; } if (newBalance >= minimumTokenBalanceForDividends) { _setBalance(account, newBalance); tokenHoldersMap.set(account, newBalance); } else { _setBalance(account, 0); tokenHoldersMap.remove(account); } processAccount(account, true); } function _setBalance(address account, uint256 newBalance) private { uint256 currentBalance = tokenHolderBalances[account]; if (newBalance > currentBalance) { uint256 increaseAmount = newBalance - currentBalance; totalSupply += increaseAmount; tokenHolderBalances[account] += increaseAmount; magnifiedDividendCorrections[account] -= int256(increaseAmount * magnifiedDividendPerShare); } else if (newBalance < currentBalance) { uint256 decreaseAmount = currentBalance - newBalance; totalSupply -= decreaseAmount; tokenHolderBalances[account] -= decreaseAmount; magnifiedDividendCorrections[account] += int256(decreaseAmount * magnifiedDividendPerShare); } } function _safeTransferETH(address to, uint256 value) private returns (bool) { (bool success, ) = to.call{value: value, gas: 30_000}(new bytes(0)); return success; } receive() external payable {} fallback() external payable {} }
// SPDX-License-Identifier: MIT // Factory: gemlabs pragma solidity ^0.8.24; interface IDividendTracker { event ExcludeFromDividends(address indexed account); event ClaimWaitUpdated(uint256 indexed newValue, uint256 indexed oldValue); event Claim(address indexed account, uint256 amount, bool indexed automatic); event DividendsDistributed(address indexed from, uint256 weiAmount); event DividendWithdrawn(address indexed to, uint256 weiAmount); error InvalidClaimWait(uint256 provided, uint256 min, uint256 max); error ClaimWaitAlreadySet(uint256 provided); error NoTotalSupply(); function excludeFromDividends(address account) external; function updateClaimWait(uint256 newClaimWait) external; function getNumberOfTokenHolders() external view returns (uint256); function getTokenHolderBalance(address account) external view returns (uint256); function getAccount( address _account ) external view returns ( address account, int256 index, int256 iterationsUntilProcessed, uint256 withdrawableDividends, uint256 totalDividends, uint256 lastClaimTime, uint256 nextClaimTime, uint256 secondsUntilAutoClaimAvailable ); function getAccountAtIndex( uint256 index ) external view returns (address, int256, int256, uint256, uint256, uint256, uint256, uint256); function process(uint256 gas) external returns (uint256, uint256, uint256); function processAccount(address payable account, bool automatic) external returns (bool); function distributeDividends(uint256 amount) external; function withdrawDividend() external; function withdrawableDividendOf(address _owner) external view returns (uint256); function withdrawnDividendOf(address _owner) external view returns (uint256); function accumulativeDividendOf(address _owner) external view returns (uint256); function getLargestHolder() external view returns (address largestHolder, uint256 largestBalance); function setBalance(address payable account, uint256 newBalance) external; }
// SPDX-License-Identifier: MIT // Factory: gemlabs pragma solidity ^0.8.24; library IterableMapping { struct Map { address[] keys; mapping(address => uint) values; mapping(address => uint) indexOf; mapping(address => bool) inserted; } function get(Map storage map, address key) internal view returns (uint) { return map.values[key]; } function getIndexOfKey(Map storage map, address key) internal view returns (int) { if (!map.inserted[key]) { return -1; } return int(map.indexOf[key]); } function getKeyAtIndex(Map storage map, uint index) internal view returns (address) { return map.keys[index]; } function size(Map storage map) internal view returns (uint) { return map.keys.length; } function set(Map storage map, address key, uint val) internal { if (map.inserted[key]) { map.values[key] = val; } else { map.inserted[key] = true; map.values[key] = val; map.indexOf[key] = map.keys.length; map.keys.push(key); } } function remove(Map storage map, address key) internal { if (!map.inserted[key]) { return; } delete map.inserted[key]; delete map.values[key]; uint index = map.indexOf[key]; uint lastIndex = map.keys.length - 1; address lastKey = map.keys[lastIndex]; map.indexOf[lastKey] = index; delete map.indexOf[key]; map.keys[index] = lastKey; map.keys.pop(); } }
{ "optimizer": { "enabled": true, "runs": 200 }, "viaIR": true, "evmVersion": "paris", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint256","name":"_initialSupply","type":"uint256"},{"internalType":"address","name":"_router","type":"address"},{"internalType":"uint256","name":"_minimumTokenBalanceForDividendsPct","type":"uint256"},{"internalType":"address","name":"_teamWallet","type":"address"},{"internalType":"uint256","name":"_teamFee","type":"uint256"},{"internalType":"uint256","name":"_dividendsFee","type":"uint256"},{"internalType":"uint256","name":"_burnFee","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"pair","type":"address"}],"name":"CannotRemoveUniswapPair","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC20InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC20InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"ERC20InvalidSpender","type":"error"},{"inputs":[{"internalType":"uint256","name":"totalFee","type":"uint256"}],"name":"InvalidFee","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"address","name":"pair","type":"address"},{"internalType":"bool","name":"value","type":"bool"}],"name":"PairAlreadySetToValue","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"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":"account","type":"address"},{"indexed":false,"internalType":"bool","name":"isExcluded","type":"bool"}],"name":"ExcludeFromFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"iterations","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"claims","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lastProcessedIndex","type":"uint256"},{"indexed":true,"internalType":"bool","name":"automatic","type":"bool"},{"indexed":false,"internalType":"uint256","name":"gas","type":"uint256"},{"indexed":true,"internalType":"address","name":"processor","type":"address"}],"name":"ProcessedDividendTracker","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"SendDividends","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pair","type":"address"},{"indexed":true,"internalType":"bool","name":"value","type":"bool"}],"name":"SetAutomatedMarketMakerPair","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"PINK_LOCK_CONTRACT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"_isExcludedFromFees","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"automatedMarketMakerPairs","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"burnFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deployerWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dividendTracker","outputs":[{"internalType":"contract DividendTracker","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dividendsFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"excludeFromDividends","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"excluded","type":"bool"}],"name":"excludeFromFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isExcludedFromFees","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"gas","type":"uint256"}],"name":"processDividendTracker","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"},{"internalType":"bool","name":"value","type":"bool"}],"name":"setAutomatedMarketMakerPair","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setBurnFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setDividendsFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setTeamFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"wallet","type":"address"}],"name":"setTeamWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"swapTokensAtAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"teamFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"teamWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uniswapV2Pair","outputs":[{"internalType":"contract IUniswapV2Pair","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uniswapV2Router","outputs":[{"internalType":"contract IUniswapV2Router02","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"claimWait","type":"uint256"}],"name":"updateClaimWait","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"withdrawableDividendOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
604060808152346200053857620032ce803803806200001e816200053d565b928339810161012082820312620005385781516001600160401b0381116200053857816200004e91840162000563565b602083015190916001600160401b03821162000538576200007191840162000563565b9083830151906200008560608501620005d5565b506080840151906200009a60a08601620005d5565b9360c08601519061010060e08801519701519280519060018060401b038211620002955760035490600182811c921680156200052d575b6020831014620004005781601f849311620004b8575b50602090601f83116001146200042d5760009262000421575b50508160011b916000199060031b1c1916176003555b8051906001600160401b038211620002955760045490600182811c9216801562000416575b6020831014620004005781601f8493116200038b575b50602090601f8311600114620002fc57600092620002f0575b50508160011b916000199060031b1c1916176004555b3315620002d857600580546001600160a01b031980821633908117909355976001600160a01b03976200021195946200020b9490938a92919083167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a36001600655338b600b541617600b551689600c541617600c5580600d5581600e5583600f55620005ea565b620005ea565b9161271092838111620002c15750620f42408104600a55818102918183041490151715620002ab5784519161131990818401906001600160401b038211858310176200029557602093859362001fb585390481520301906000f080156200028a5716906009541617600955516119bc9081620005f98239f35b83513d6000823e3d90fd5b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60249087519063179c637760e11b82526004820152fd5b8651631e4fbdf760e01b815260006004820152602490fd5b0151905038806200016a565b6004600090815293507f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b91905b601f19841685106200036f576001945083601f1981161062000355575b505050811b0160045562000180565b015160001960f88460031b161c1916905538808062000346565b8181015183556020948501946001909301929091019062000329565b60046000529091507f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b601f840160051c81019160208510620003f5575b90601f859493920160051c01905b818110620003e5575062000151565b60008155849350600101620003d6565b9091508190620003c8565b634e487b7160e01b600052602260045260246000fd5b91607f16916200013b565b01519050388062000100565b600360009081527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b9350601f198516905b8181106200049f575090846001959493921062000485575b505050811b0160035562000116565b015160001960f88460031b161c1916905538808062000476565b929360206001819287860151815501950193016200045e565b60036000529091507fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b601f840160051c8101916020851062000522575b90601f859493920160051c01905b818110620005125750620000e7565b6000815584935060010162000503565b9091508190620004f5565b91607f1691620000d1565b600080fd5b6040519190601f01601f191682016001600160401b038111838210176200029557604052565b919080601f84011215620005385782516001600160401b038111620002955760209062000599601f8201601f191683016200053d565b92818452828287010111620005385760005b818110620005c157508260009394955001015290565b8581018301518482018401528201620005ab565b51906001600160a01b03821682036200053857565b91908201809211620002ab5756fe6080604081815260049182361015610022575b505050361561002057600080fd5b005b600092833560e01c91826306fdde0314610bf557508163095ea7b314610bcb5781630acafbec14610b9c5781631525ff7d14610b535781631694505e14610b2a57816318160ddd14610b0b57816323b872dd14610ace5781632c1f521614610aa5578163313ce56714610a8957816331e79db014610a1457816342966c68146109f657816349bd5a5e146109cd5781634bf2c7c91461099e578382634e71d92d14610917575081634fbee1931461037457816359927044146108ee5781635d60c7be146108c5578163700bb191146107ef57816370a08231146107b8578163715018a61461075a57816379cc67901461072a57816387c34ae2146106fb5781638da5cb5b146106d257816395d89b41146105cd5781639a7a23d6146105b2578163a8b9d24014610516578163a9059cbb146104e5578163aeca8f9f146104c6578163b62496f514610488578163c02466681461041f578163d7c94efd14610400578163dd62ed3e146103b2578163e0bf7fd114610374578163e2f4560514610355578163e6ec64ec1461031157838263e98030c71461028e57508163f2fde38b146101f9575063fce589d8146101d85780610012565b346101f557816003193601126101f557602090600f549051908152f35b5080fd5b90503461028a57602036600319011261028a57610214610d2f565b9061021d610f3c565b6001600160a01b03918216928315610274575050600554826bffffffffffffffffffffffff60a01b821617600555167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a380f35b51631e4fbdf760e01b8152908101849052602490fd5b8280fd5b8091843461030d57602036600319011261030d576102aa610f3c565b6009546001600160a01b031691823b15610308578392602484928451958693849263e98030c760e01b84528035908401525af19081156102ff57506102ec5750f35b6102f590610d8f565b6102fc5780f35b80fd5b513d84823e3d90fd5b505050fd5b5050fd5b90503461028a57602036600319011261028a5780359161032f610f3c565b6127108311610340575050600e5580f35b91602492519163179c637760e11b8352820152fd5b5050346101f557816003193601126101f557602090600a549051908152f35b5050346101f55760203660031901126101f55760209160ff9082906001600160a01b0361039f610d2f565b1681526010855220541690519015158152f35b5050346101f557806003193601126101f5576020916103cf610d2f565b826103d8610d4a565b6001600160a01b03928316845260018652922091166000908152908352819020549051908152f35b5050346101f557816003193601126101f557602090600e549051908152f35b5050346101f5577f9d8f7706ea1113d1a167b526eca956215946dd36cc7df39eb16180222d8b5df7602061045236610d60565b9061045b610f3c565b6001600160a01b031680865260108352848620805460ff191660ff8415151617905593519015158152a280f35b5050346101f55760203660031901126101f55760209160ff9082906001600160a01b036104b3610d2f565b1681526011855220541690519015158152f35b5050346101f557816003193601126101f557602090600d549051908152f35b5050346101f557806003193601126101f55760209061050f610505610d2f565b602435903361103b565b5160018152f35b8383346101f5576020928360031936011261028a5783610534610d2f565b60095484516302a2e74960e61b81526001600160a01b039283169481019490945283916024918391165afa9283156105a7578093610575575b505051908152f35b909192508382813d83116105a0575b61058e8183610db9565b810103126102fc57505190838061056d565b503d610584565b8251903d90823e3d90fd5b83346102fc576105ca6105c436610d60565b90610df6565b80f35b8383346101f557816003193601126101f55780519180938054916001908360011c92600185169485156106c8575b60209586861081146106b5578589529081156106915750600114610639575b610635878761062b828c0383610db9565b5191829182610ce6565b0390f35b81529295507f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b5b82841061067e57505050826106359461062b9282010194868061061a565b8054868501880152928601928101610660565b60ff19168887015250505050151560051b830101925061062b82610635868061061a565b634e487b7160e01b845260228352602484fd5b93607f16936105fb565b5050346101f557816003193601126101f55760055490516001600160a01b039091168152602090f35b90503461028a57602036600319011261028a57803591610719610f3c565b6127108311610340575050600d5580f35b5050346101f5573660031901126102fc576105ca610746610d2f565b60243590610755823383610f68565b611091565b83346102fc57806003193601126102fc57610773610f3c565b600580546001600160a01b031981169091556000906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b5050346101f55760203660031901126101f55760209181906001600160a01b036107e0610d2f565b16815280845220549051908152f35b9190503461028a57602036600319011261028a5760095481516001624d3b8760e01b0319815283359381018490529291906060908490602490829088906001600160a01b03165af19081156108bc57849385908693610886575b50815194855260208501528301526060820152817fc864333d6121033635ab41b29ae52f10a22cf4438c3e4f1c4c68518feb2f8a9860803293a380f35b919450506108ac915060603d6060116108b5575b6108a48183610db9565b810190610ddb565b91939038610849565b503d61089a565b513d85823e3d90fd5b5050346101f557816003193601126101f557600b5490516001600160a01b039091168152602090f35b5050346101f557816003193601126101f557600c5490516001600160a01b039091168152602090f35b9291503461030d578260031936011261030d57602090604460018060a01b0360095416918451958693849263bc4c4b3760e01b845233908401528160248401525af19081156102ff5750610969575080f35b6020813d602011610996575b8161098260209383610db9565b810103126101f55751801515036102fc5780f35b3d9150610975565b90503461028a57602036600319011261028a578035916109bc610f3c565b6127108311610340575050600f5580f35b5050346101f557816003193601126101f55760085490516001600160a01b039091168152602090f35b8390346101f55760203660031901126101f5576105ca903533611091565b9190503461028a57602036600319011261028a5782610a31610d2f565b610a39610f3c565b6009546001600160a01b039190821690813b15610a8557836024928651978895869463031e79db60e41b865216908401525af19081156102ff5750610a7c575080f35b6105ca90610d8f565b8380fd5b5050346101f557816003193601126101f5576020905160128152f35b5050346101f557816003193601126101f55760095490516001600160a01b039091168152602090f35b5050346101f55760603660031901126101f55760209061050f610aef610d2f565b610af7610d4a565b60443591610b06833383610f68565b61103b565b5050346101f557816003193601126101f5576020906002549051908152f35b5050346101f557816003193601126101f55760075490516001600160a01b039091168152602090f35b8390346101f55760203660031901126101f557356001600160a01b038116908190036101f557610b81610f3c565b6bffffffffffffffffffffffff60a01b600c541617600c5580f35b5050346101f557816003193601126101f5576020905173dd6e31a046b828cbbafb939c2a394629aff8bbdc8152f35b5050346101f557806003193601126101f55760209061050f610beb610d2f565b60243590336110ac565b92915034610a855783600319360112610a8557600354600181811c9186908281168015610cdc575b6020958686108214610cc95750848852908115610ca75750600114610c4e575b610635868661062b828b0383610db9565b929550600383527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b5b828410610c9457505050826106359461062b928201019438610c3d565b8054868501880152928601928101610c77565b60ff191687860152505050151560051b830101925061062b8261063538610c3d565b634e487b7160e01b845260229052602483fd5b93607f1693610c1d565b6020808252825181830181905290939260005b828110610d1b57505060409293506000838284010152601f8019910116010190565b818101860151848201604001528501610cf9565b600435906001600160a01b0382168203610d4557565b600080fd5b602435906001600160a01b0382168203610d4557565b6040906003190112610d45576004356001600160a01b0381168103610d4557906024358015158103610d455790565b67ffffffffffffffff8111610da357604052565b634e487b7160e01b600052604160045260246000fd5b90601f8019910116810190811067ffffffffffffffff821117610da357604052565b90816060910312610d45578051916040602083015192015190565b600b546000906001600160a01b039081163303610f36578080600854169316928314610f1d57828252601160205260ff604083205416938015158095151514610eff578383526011602052610e5a81604085209060ff801983541691151516179055565b610e86575b50807fffa9187bf1f18bf477bd0ea1bcbb64e93b6a98132473929edfce215cd9b16fab91a3565b60095416803b156101f55781809160246040518094819363031e79db60e41b83528860048401525af18015610ef457907fffa9187bf1f18bf477bd0ea1bcbb64e93b6a98132473929edfce215cd9b16fab9291610ee5575b5090610e5f565b610eee90610d8f565b38610ede565b6040513d84823e3d90fd5b6044848660405191632b100e0760e21b835260048301526024820152fd5b6040516341ae7cb360e11b815260048101849052602490fd5b50505050565b6005546001600160a01b03163303610f5057565b60405163118cdaa760e01b8152336004820152602490fd5b9160018060a01b038093169160009383855260016020526040938486209183169182875260205284862054926000198403610fa7575b50505050505050565b84841061100b57508015610ff3578115610fdb57855260016020528385209085526020520391205538808080808080610f9e565b8451634a1406b160e11b815260048101879052602490fd5b845163e602df0560e01b815260048101879052602490fd5b8551637dc7a0d960e11b81526001600160a01b039190911660048201526024810184905260448101859052606490fd5b91906001600160a01b03808416156110785781161561105f5761105d926111a2565b565b60405163ec442f0560e01b815260006004820152602490fd5b604051634b637e8f60e11b815260006004820152602490fd5b906001600160a01b0382161561107857600061105d926111a2565b6001600160a01b03908116918215611126571691821561110d5760207f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925918360005260018252604060002085600052825280604060002055604051908152a3565b604051634a1406b160e11b815260006004820152602490fd5b60405163e602df0560e01b815260006004820152602490fd5b9190820180921161114c57565b634e487b7160e01b600052601160045260246000fd5b8181029291811591840414171561114c57565b811561117f570490565b634e487b7160e01b600052601260045260246000fd5b9190820391821161114c57565b9190811561155f573060009081526020819052604090205492600a54841015936111dd6111d4600d54600e549061113f565b600f549061113f565b948061154a575b8061151f575b806114f8575b806114d1575b6113f3575b5061127e9361121361120f60125460ff1690565b1590565b6001600160a01b038316600090815260116020526040902061123b9061120f905b5460ff1690565b806113c8575b6113c0575b6001600160a01b038316600090815260106020526040902061126790611234565b8015611399575b611391575b61135f575b506115d6565b61128d61120f60125460ff1690565b61129357565b6009546112b0906001600160a01b03165b6001600160a01b031690565b6040516001624d3b8760e01b031981526207a120600482015290606090829060249082906000905af16000918160009160009361133a575b506112f257505050565b6040805193845260208401919091528201526207a120606082015232906001907fc864333d6121033635ab41b29ae52f10a22cf4438c3e4f1c4c68518feb2f8a9890608090a3565b91509250611357915060603d6060116108b5576108a48183610db9565b9192386112e8565b9261137961137161138a939583611162565b612710900490565b906113858230876115d6565b611195565b9138611278565b506000611273565b506001600160a01b03841660009081526010602052604090206113bb90611234565b61126e565b506000611246565b506001600160a01b03841660009081526011602052604090206113ee9061120f90611234565b611241565b61140e90611409600160ff196012541617601255565b6116ae565b479380611430575b61127e945061142a60ff1960125416601255565b936111fb565b84600e5480611498575b50600f549081611466575b50508461127e95611457575b50611416565b611460906118c4565b38611451565b611474611479928492611162565b611175565b946114848630611091565b61127e9561149191611195565b9438611445565b819650826114746114ac926114ca94611162565b600c546114c39082906001600160a01b031661184a565b5086611195565b943861143a565b506005546114e7906001600160a01b03166112a4565b6001600160a01b03841614156111f6565b5060055461150e906001600160a01b03166112a4565b6001600160a01b03831614156111f0565b506001600160a01b03821660009081526011602052604090206115459061120f90611234565b6111ea565b5061155a61120f60125460ff1690565b6111e4565b61105d92600092506001600160a01b0390811691826115b757600080516020611967833981519152916020916115978660025461113f565b6002555b1693846115ac575b604051908152a3565b8481528082526115a3565b828452602084815260008051602061196783398151915292909161159b565b6001600160a01b038082169290918361163d5750600080516020611967833981519152916020916116098660025461113f565b6002555b169384611625578060025403600255604051908152a3565b846000526000825260406000208181540190556115a3565b6000908482528160205260408220549086821061167c57509181604087602095886000805160206119678339815191529896528387520391205561160d565b60405163391434e360e21b81526001600160a01b03919091166004820152602481019190915260448101869052606490fd5b60408051916060830183811067ffffffffffffffff821117610da35782526002835260209081840190833683378451156117ef5730825260075484516315ab88c960e31b81526001600160a01b0392909183168583600481845afa92831561183f57600093611805575b50875192600193600110156117ef576117399185849216898b0152306110ac565b82600754169461012c42019384421161114c57863b15610d455791879895949391985198899663791ac94760e01b885260a488019260048901526000602489015260a060448901525180925260c4870195936000905b8382106117d5575050505050506000838195938193306064840152608483015203925af19081156117cb57506117c25750565b61105d90610d8f565b513d6000823e3d90fd5b8551811688528b985096820196948201949084019061178f565b634e487b7160e01b600052603260045260246000fd5b8681819593953d8311611838575b61181d8183610db9565b810103126101f557519084821682036102fc57509138611718565b503d611813565b87513d6000823e3d90fd5b60405167ffffffffffffffff91906020810183811182821017610da3576040526000808095819482809552617530f1913d156118bf573d9182116118ab57604051916118a0601f8201601f191660200184610db9565b825260203d92013e90565b634e487b7160e01b81526041600452602490fd5b505090565b6009546001600160a01b03906118dd908390831661184a565b6118e5575050565b6009541690813b15610d455760008092602460405180958193633243c79160e01b83528660048401525af190811561195a577fb0cc2628d6d644cf6be9d8110e142297ac910d6d8026d795a99f272fd9ad60b19260209261194b575b50604051908152a1565b61195490610d8f565b38611941565b6040513d6000823e3d90fdfeddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220977d4498ffc2e796f45985e7faaf53e4b11e05ce3b0a0aba493f9b74ddcc053264736f6c634300081800336080346100bc57601f61131938819003918201601f19168301916001600160401b038311848410176100c1578084926020946040528339810103126100bc575133156100a35760008054336001600160a01b0319821681178355604051939290916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a3610e10600955600a5561124190816100d88239f35b604051631e4fbdf760e01b815260006004820152602490fd5b600080fd5b634e487b7160e01b600052604160045260246000fdfe608060408181526004918236101561001f575b505050361561001d57005b005b600090813560e01c90816309bbedde1461084e5750806318160ddd1461082f578063226cfa3d146107f557806327ce0147146107c45780633009a609146107a557806331e79db0146107245780633243c791146106605780633a7960e0146106415780634e7b827f146106025780635183d6fd146105e25780636a474002146105c45780636f2789ec146105a5578063715018a61461054b57806385a6b3ae1461052c5780638da5cb5b14610504578063a2ec70d2146103f4578063a8b9d240146104cc578063aafd847a14610492578063bc4c4b371461044d578063be10b6141461042e578063d3573e42146103f4578063e30443bc146103c0578063e98030c714610314578063f223273a14610296578063f2fde38b14610207578063fbcbc0f1146101845763ffb2c479036100125734610181576020366003190112610181575061016f60609235610e01565b91929081519384526020840152820152f35b80fd5b5091346102035760203660031901126102035735916001600160a01b038316830361018157506101b66101ff92610d30565b97516001600160a01b039097168752602087019590955260408601939093526060850191909152608084015260a083015260c082015260e0810191909152908190610100820190565b0390f35b8280fd5b50919034610203576020366003190112610203576001600160a01b038235818116939192908490036102925761023b610f1b565b831561027c57505082546001600160a01b0319811683178455167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b51631e4fbdf760e01b8152908101849052602490fd5b8480fd5b5034610181578060031936011261018157806001805482805b8281106102d057505084516001600160a01b03909416845250506020820152f35b6102d981610cca565b905460039190911b1c6001600160a01b0316808352600d60205287832054868111610308575b505083016102af565b909650945083886102ff565b50913461020357602036600319011261020357803591610332610f1b565b610e1080841080156103b4575b6103905750600954831461037b57505080600955807f474ea64804364a1e29a4487ddb63c3342a2dd826ccd8acf48825e680a0e6f20f8380a380f35b916024925191632c42b16760e01b8352820152fd5b90926064935192630100828360e11b84528301526024820152620151806044820152fd5b5062015180841161033f565b5090346103f057366003190112610181576103ed6103dc61086a565b6103e4610f1b565b60243590610ab6565b80f35b5080fd5b50913461020357602036600319011261020357356001600160a01b038116908190036102035782829160209452600d845220549051908152f35b5090346103f057816003193601126103f057602090600a549051908152f35b5090346103f057806003193601126103f05761046761086a565b602435928315158403610181575060209261048991610484610f1b565b6109f5565b90519015158152f35b50913461020357602036600319011261020357356001600160a01b038116908190036102035782829160209452600f845220549051908152f35b5091346102035760203660031901126102035735916001600160a01b038316830361018157506104fd6020926109c5565b9051908152f35b5090346103f057816003193601126103f057905490516001600160a01b039091168152602090f35b5090346103f057816003193601126103f0576020906008549051908152f35b5034610181578060031936011261018157610564610f1b565b80546001600160a01b03198116825581906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b5090346103f057816003193601126103f0576020906009549051908152f35b50346101815780600319360112610181576105de3361108c565b5080f35b503461018157602036600319011261018157506101b66101ff9235610965565b50913461020357602036600319011261020357356001600160a01b0381169081900361020357818360ff9260209552600b855220541690519015158152f35b5090346103f057816003193601126103f0576020906007549051908152f35b5090346103f05760203660031901126103f05782359061067e610f1b565b6006548015610714578215908115610694578480f35b60075491608085901b90600160801b868304141715610701576106f5959650906106c092910490610958565b600755518181527fa493a9229478c3fcd73f66d2cdeb7f94fd0f341da924d1054236d7845411651160203392a2600854610958565b60085580388080808480f35b634e487b7160e01b865260118752602486fd5b8151636328a90f60e11b81528590fd5b50913461020357602036600319011261020357356001600160a01b03811691908281036107a15761077a91610757610f1b565b838552600b6020528420805460ff1916600117905561077581610f47565b610fad565b7fa878b31040b2e6d0a9a3d3361209db3908ba62014b0dca52adbaee451d128b258280a280f35b8380fd5b5090346103f057816003193601126103f0576020906005549051908152f35b5091346102035760203660031901126102035735916001600160a01b038316830361018157506104fd6020926108b7565b50913461020357602036600319011261020357356001600160a01b038116908190036102035782829160209452600c845220549051908152f35b5090346103f057816003193601126103f0576020906006549051908152f35b9050346103f057816003193601126103f0576020906001548152f35b600435906001600160a01b038216820361088057565b600080fd5b919091600083820193841291129080158216911516176108a157565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b03166000908152600d6020908152604080832054600e90925282205460075490918181029190848212600160ff1b82141661093157818305149015171561091d579061090991610885565b81811215610915575090565b905060801c90565b634e487b7160e01b83526011600452602483fd5b634e487b7160e01b85526011600452602485fd5b818102929181159184041417156108a157565b919082018092116108a157565b6001548110156109a25761097b61099291610cca565b905460039190911b1c6001600160a01b0316610d30565b9697959694959394929391929091565b5060009060001990819083908190819081908190565b919082039182116108a157565b6109f2906109d2816108b7565b6001600160a01b039091166000908152600f6020526040902054906109b8565b90565b906109ff8261108c565b9182610a0d57505050600090565b60207fa2c38e2d2fb7e3e1912d937fd1ca11ed6d51864dee4cfa7a7bf02becd7acf0929160018060a01b03169283600052600c825242604060002055604051948552151593a3600190565b610a618161108c565b80610a6d575050600090565b7fa2c38e2d2fb7e3e1912d937fd1ca11ed6d51864dee4cfa7a7bf02becd7acf0926020600193848060a01b03169283600052600c825242604060002055604051908152a3600190565b6001600160a01b0381166000818152600b602090815260408083205494959460ff16610cc257600a548510610cac57838352600d8252808320548581811115610c4d57610b3591610b06916109b8565b610b1281600654610958565b600655858552600d8452828520610b2a828254610958565b905560075490610945565b848452600e8352610b4a828520918254610d17565b90555b6001600160a01b03841660009081526004602052604090205460ff1615610b9e575050506001600160a01b0316600090815260026020526040902055610b9b905b610b96610f1b565b610a58565b50565b6001600160a01b03841660009081526004602052604090209394600394805460ff191660011790556001600160a01b0386166000908152600260205260409020556001549384928685525282205568010000000000000000821015610c395750610b9b9291610c16826001610c349401600155610cca565b90919060018060a01b038084549260031b9316831b921b1916179055565b610b8e565b634e487b7160e01b81526041600452602490fd5b90808210610c5d575b5050610b4d565b610c8e91610c6a916109b8565b610c76816006546109b8565b600655858552600d8452828520610b2a8282546109b8565b848452600e8352610ca3828520918254610885565b90558438610c56565b505050610b9b92915080610775610c3492610f47565b505050505050565b600154811015610d015760016000527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60190600090565b634e487b7160e01b600052603260045260246000fd5b818103929160001380158285131691841216176108a157565b9081610d3b816111b8565b916000199160009182851215610daa575b610d55826109c5565b92610d5f836108b7565b6001600160a01b039093168152600c6020526040812054918215610da457610d8960095484610958565b915b8242811115610da0576109f2915042906109b8565b5090565b81610d8b565b9250600554808511600014610dc957610dc39085610d17565b92610d4c565b60015481811115610de757610dc391610de1916109b8565b85610885565b5050610dc382610de1565b60001981146108a15760010190565b600191600154918215610f0d57916005549260005a90866000946000985b610e32575b505050505082600555929190565b90919293949685841080610f04575b15610efd57610e4f90610df2565b968254881015610ef4575b610e6388610cca565b60018060a01b0391549060031b1c1680600052600c602052610e896040600020546111ec565b610ec8575b50610e9890610df2565b945a94858111610eae575b509392919081610e1f565b85610ebd610ec2928697610958565b6109b8565b93610ea3565b610ed490610b96610f1b565b610edf575b38610e8e565b97610eec610e9891610df2565b989050610ed9565b60009750610e5a565b9694610e24565b50818810610e41565b506005546000935083925090565b6000546001600160a01b03163303610f2f57565b60405163118cdaa760e01b8152336004820152602490fd5b6001600160a01b03166000818152600d602052604081205480610f6957505050565b610fa991610f9882610f7f6040946006546109b8565b600655858352600d602052838320610b2a8282546109b8565b938152600e60205220918254610885565b9055565b6001600160a01b039081166000818152600460205260408120805460ff8116156110855760ff1916905560026020528060408120556003602052604081205491600154926000199384810190811161107157611035929186611011610c1693610cca565b90549060031b1c169283865260036020528160408720558552846040812055610cca565b60015490811561105d5750019061104b82610cca565b909182549160031b1b19169055600155565b634e487b7160e01b81526031600452602490fd5b634e487b7160e01b84526011600452602484fd5b5050505050565b6001600160a01b031661109e816109c5565b90816110ab575050600090565b6000908082526020600f81526040906110c78583862054610958565b838552600f825282852055815167ffffffffffffffff908083018281118282101761119e578452859052848080808988617530f1903d156111b2573d81811161119e57845191601f8201601f19908116603f011683019081118382101761118a578552815285833d92013e5b837fee503bee2bb6a87e57bc57db795f98137327401a0e7b7ce42e37926cc1a9ca4d838551898152a215611168575050505090565b611180849584600f94959652838352848720546109b8565b9385525282205590565b634e487b7160e01b88526041600452602488fd5b634e487b7160e01b87526041600452602487fd5b50611133565b6001600160a01b031660009081526004602052604090205460ff16156111e657600360205260406000205490565b60001990565b428111611205576111fd90426109b8565b600954111590565b5060009056fea2646970667358221220793a0e8d3b5d6f63c59be1e24000ae2abef254699377f165bc11e5b9777e253764736f6c634300081800330000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000d3c21bcecceda100000000000000000000000000000018e621b64d7808c3c47bccbbd7485d23f257d26f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000033f5dcece4505afeb69c6d0f2bf856d13b2afab8000000000000000000000000000000000000000000000000000000000000009600000000000000000000000000000000000000000000000000000000000000fa00000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000004505550530000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035055500000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604081815260049182361015610022575b505050361561002057600080fd5b005b600092833560e01c91826306fdde0314610bf557508163095ea7b314610bcb5781630acafbec14610b9c5781631525ff7d14610b535781631694505e14610b2a57816318160ddd14610b0b57816323b872dd14610ace5781632c1f521614610aa5578163313ce56714610a8957816331e79db014610a1457816342966c68146109f657816349bd5a5e146109cd5781634bf2c7c91461099e578382634e71d92d14610917575081634fbee1931461037457816359927044146108ee5781635d60c7be146108c5578163700bb191146107ef57816370a08231146107b8578163715018a61461075a57816379cc67901461072a57816387c34ae2146106fb5781638da5cb5b146106d257816395d89b41146105cd5781639a7a23d6146105b2578163a8b9d24014610516578163a9059cbb146104e5578163aeca8f9f146104c6578163b62496f514610488578163c02466681461041f578163d7c94efd14610400578163dd62ed3e146103b2578163e0bf7fd114610374578163e2f4560514610355578163e6ec64ec1461031157838263e98030c71461028e57508163f2fde38b146101f9575063fce589d8146101d85780610012565b346101f557816003193601126101f557602090600f549051908152f35b5080fd5b90503461028a57602036600319011261028a57610214610d2f565b9061021d610f3c565b6001600160a01b03918216928315610274575050600554826bffffffffffffffffffffffff60a01b821617600555167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a380f35b51631e4fbdf760e01b8152908101849052602490fd5b8280fd5b8091843461030d57602036600319011261030d576102aa610f3c565b6009546001600160a01b031691823b15610308578392602484928451958693849263e98030c760e01b84528035908401525af19081156102ff57506102ec5750f35b6102f590610d8f565b6102fc5780f35b80fd5b513d84823e3d90fd5b505050fd5b5050fd5b90503461028a57602036600319011261028a5780359161032f610f3c565b6127108311610340575050600e5580f35b91602492519163179c637760e11b8352820152fd5b5050346101f557816003193601126101f557602090600a549051908152f35b5050346101f55760203660031901126101f55760209160ff9082906001600160a01b0361039f610d2f565b1681526010855220541690519015158152f35b5050346101f557806003193601126101f5576020916103cf610d2f565b826103d8610d4a565b6001600160a01b03928316845260018652922091166000908152908352819020549051908152f35b5050346101f557816003193601126101f557602090600e549051908152f35b5050346101f5577f9d8f7706ea1113d1a167b526eca956215946dd36cc7df39eb16180222d8b5df7602061045236610d60565b9061045b610f3c565b6001600160a01b031680865260108352848620805460ff191660ff8415151617905593519015158152a280f35b5050346101f55760203660031901126101f55760209160ff9082906001600160a01b036104b3610d2f565b1681526011855220541690519015158152f35b5050346101f557816003193601126101f557602090600d549051908152f35b5050346101f557806003193601126101f55760209061050f610505610d2f565b602435903361103b565b5160018152f35b8383346101f5576020928360031936011261028a5783610534610d2f565b60095484516302a2e74960e61b81526001600160a01b039283169481019490945283916024918391165afa9283156105a7578093610575575b505051908152f35b909192508382813d83116105a0575b61058e8183610db9565b810103126102fc57505190838061056d565b503d610584565b8251903d90823e3d90fd5b83346102fc576105ca6105c436610d60565b90610df6565b80f35b8383346101f557816003193601126101f55780519180938054916001908360011c92600185169485156106c8575b60209586861081146106b5578589529081156106915750600114610639575b610635878761062b828c0383610db9565b5191829182610ce6565b0390f35b81529295507f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b5b82841061067e57505050826106359461062b9282010194868061061a565b8054868501880152928601928101610660565b60ff19168887015250505050151560051b830101925061062b82610635868061061a565b634e487b7160e01b845260228352602484fd5b93607f16936105fb565b5050346101f557816003193601126101f55760055490516001600160a01b039091168152602090f35b90503461028a57602036600319011261028a57803591610719610f3c565b6127108311610340575050600d5580f35b5050346101f5573660031901126102fc576105ca610746610d2f565b60243590610755823383610f68565b611091565b83346102fc57806003193601126102fc57610773610f3c565b600580546001600160a01b031981169091556000906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b5050346101f55760203660031901126101f55760209181906001600160a01b036107e0610d2f565b16815280845220549051908152f35b9190503461028a57602036600319011261028a5760095481516001624d3b8760e01b0319815283359381018490529291906060908490602490829088906001600160a01b03165af19081156108bc57849385908693610886575b50815194855260208501528301526060820152817fc864333d6121033635ab41b29ae52f10a22cf4438c3e4f1c4c68518feb2f8a9860803293a380f35b919450506108ac915060603d6060116108b5575b6108a48183610db9565b810190610ddb565b91939038610849565b503d61089a565b513d85823e3d90fd5b5050346101f557816003193601126101f557600b5490516001600160a01b039091168152602090f35b5050346101f557816003193601126101f557600c5490516001600160a01b039091168152602090f35b9291503461030d578260031936011261030d57602090604460018060a01b0360095416918451958693849263bc4c4b3760e01b845233908401528160248401525af19081156102ff5750610969575080f35b6020813d602011610996575b8161098260209383610db9565b810103126101f55751801515036102fc5780f35b3d9150610975565b90503461028a57602036600319011261028a578035916109bc610f3c565b6127108311610340575050600f5580f35b5050346101f557816003193601126101f55760085490516001600160a01b039091168152602090f35b8390346101f55760203660031901126101f5576105ca903533611091565b9190503461028a57602036600319011261028a5782610a31610d2f565b610a39610f3c565b6009546001600160a01b039190821690813b15610a8557836024928651978895869463031e79db60e41b865216908401525af19081156102ff5750610a7c575080f35b6105ca90610d8f565b8380fd5b5050346101f557816003193601126101f5576020905160128152f35b5050346101f557816003193601126101f55760095490516001600160a01b039091168152602090f35b5050346101f55760603660031901126101f55760209061050f610aef610d2f565b610af7610d4a565b60443591610b06833383610f68565b61103b565b5050346101f557816003193601126101f5576020906002549051908152f35b5050346101f557816003193601126101f55760075490516001600160a01b039091168152602090f35b8390346101f55760203660031901126101f557356001600160a01b038116908190036101f557610b81610f3c565b6bffffffffffffffffffffffff60a01b600c541617600c5580f35b5050346101f557816003193601126101f5576020905173dd6e31a046b828cbbafb939c2a394629aff8bbdc8152f35b5050346101f557806003193601126101f55760209061050f610beb610d2f565b60243590336110ac565b92915034610a855783600319360112610a8557600354600181811c9186908281168015610cdc575b6020958686108214610cc95750848852908115610ca75750600114610c4e575b610635868661062b828b0383610db9565b929550600383527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b5b828410610c9457505050826106359461062b928201019438610c3d565b8054868501880152928601928101610c77565b60ff191687860152505050151560051b830101925061062b8261063538610c3d565b634e487b7160e01b845260229052602483fd5b93607f1693610c1d565b6020808252825181830181905290939260005b828110610d1b57505060409293506000838284010152601f8019910116010190565b818101860151848201604001528501610cf9565b600435906001600160a01b0382168203610d4557565b600080fd5b602435906001600160a01b0382168203610d4557565b6040906003190112610d45576004356001600160a01b0381168103610d4557906024358015158103610d455790565b67ffffffffffffffff8111610da357604052565b634e487b7160e01b600052604160045260246000fd5b90601f8019910116810190811067ffffffffffffffff821117610da357604052565b90816060910312610d45578051916040602083015192015190565b600b546000906001600160a01b039081163303610f36578080600854169316928314610f1d57828252601160205260ff604083205416938015158095151514610eff578383526011602052610e5a81604085209060ff801983541691151516179055565b610e86575b50807fffa9187bf1f18bf477bd0ea1bcbb64e93b6a98132473929edfce215cd9b16fab91a3565b60095416803b156101f55781809160246040518094819363031e79db60e41b83528860048401525af18015610ef457907fffa9187bf1f18bf477bd0ea1bcbb64e93b6a98132473929edfce215cd9b16fab9291610ee5575b5090610e5f565b610eee90610d8f565b38610ede565b6040513d84823e3d90fd5b6044848660405191632b100e0760e21b835260048301526024820152fd5b6040516341ae7cb360e11b815260048101849052602490fd5b50505050565b6005546001600160a01b03163303610f5057565b60405163118cdaa760e01b8152336004820152602490fd5b9160018060a01b038093169160009383855260016020526040938486209183169182875260205284862054926000198403610fa7575b50505050505050565b84841061100b57508015610ff3578115610fdb57855260016020528385209085526020520391205538808080808080610f9e565b8451634a1406b160e11b815260048101879052602490fd5b845163e602df0560e01b815260048101879052602490fd5b8551637dc7a0d960e11b81526001600160a01b039190911660048201526024810184905260448101859052606490fd5b91906001600160a01b03808416156110785781161561105f5761105d926111a2565b565b60405163ec442f0560e01b815260006004820152602490fd5b604051634b637e8f60e11b815260006004820152602490fd5b906001600160a01b0382161561107857600061105d926111a2565b6001600160a01b03908116918215611126571691821561110d5760207f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925918360005260018252604060002085600052825280604060002055604051908152a3565b604051634a1406b160e11b815260006004820152602490fd5b60405163e602df0560e01b815260006004820152602490fd5b9190820180921161114c57565b634e487b7160e01b600052601160045260246000fd5b8181029291811591840414171561114c57565b811561117f570490565b634e487b7160e01b600052601260045260246000fd5b9190820391821161114c57565b9190811561155f573060009081526020819052604090205492600a54841015936111dd6111d4600d54600e549061113f565b600f549061113f565b948061154a575b8061151f575b806114f8575b806114d1575b6113f3575b5061127e9361121361120f60125460ff1690565b1590565b6001600160a01b038316600090815260116020526040902061123b9061120f905b5460ff1690565b806113c8575b6113c0575b6001600160a01b038316600090815260106020526040902061126790611234565b8015611399575b611391575b61135f575b506115d6565b61128d61120f60125460ff1690565b61129357565b6009546112b0906001600160a01b03165b6001600160a01b031690565b6040516001624d3b8760e01b031981526207a120600482015290606090829060249082906000905af16000918160009160009361133a575b506112f257505050565b6040805193845260208401919091528201526207a120606082015232906001907fc864333d6121033635ab41b29ae52f10a22cf4438c3e4f1c4c68518feb2f8a9890608090a3565b91509250611357915060603d6060116108b5576108a48183610db9565b9192386112e8565b9261137961137161138a939583611162565b612710900490565b906113858230876115d6565b611195565b9138611278565b506000611273565b506001600160a01b03841660009081526010602052604090206113bb90611234565b61126e565b506000611246565b506001600160a01b03841660009081526011602052604090206113ee9061120f90611234565b611241565b61140e90611409600160ff196012541617601255565b6116ae565b479380611430575b61127e945061142a60ff1960125416601255565b936111fb565b84600e5480611498575b50600f549081611466575b50508461127e95611457575b50611416565b611460906118c4565b38611451565b611474611479928492611162565b611175565b946114848630611091565b61127e9561149191611195565b9438611445565b819650826114746114ac926114ca94611162565b600c546114c39082906001600160a01b031661184a565b5086611195565b943861143a565b506005546114e7906001600160a01b03166112a4565b6001600160a01b03841614156111f6565b5060055461150e906001600160a01b03166112a4565b6001600160a01b03831614156111f0565b506001600160a01b03821660009081526011602052604090206115459061120f90611234565b6111ea565b5061155a61120f60125460ff1690565b6111e4565b61105d92600092506001600160a01b0390811691826115b757600080516020611967833981519152916020916115978660025461113f565b6002555b1693846115ac575b604051908152a3565b8481528082526115a3565b828452602084815260008051602061196783398151915292909161159b565b6001600160a01b038082169290918361163d5750600080516020611967833981519152916020916116098660025461113f565b6002555b169384611625578060025403600255604051908152a3565b846000526000825260406000208181540190556115a3565b6000908482528160205260408220549086821061167c57509181604087602095886000805160206119678339815191529896528387520391205561160d565b60405163391434e360e21b81526001600160a01b03919091166004820152602481019190915260448101869052606490fd5b60408051916060830183811067ffffffffffffffff821117610da35782526002835260209081840190833683378451156117ef5730825260075484516315ab88c960e31b81526001600160a01b0392909183168583600481845afa92831561183f57600093611805575b50875192600193600110156117ef576117399185849216898b0152306110ac565b82600754169461012c42019384421161114c57863b15610d455791879895949391985198899663791ac94760e01b885260a488019260048901526000602489015260a060448901525180925260c4870195936000905b8382106117d5575050505050506000838195938193306064840152608483015203925af19081156117cb57506117c25750565b61105d90610d8f565b513d6000823e3d90fd5b8551811688528b985096820196948201949084019061178f565b634e487b7160e01b600052603260045260246000fd5b8681819593953d8311611838575b61181d8183610db9565b810103126101f557519084821682036102fc57509138611718565b503d611813565b87513d6000823e3d90fd5b60405167ffffffffffffffff91906020810183811182821017610da3576040526000808095819482809552617530f1913d156118bf573d9182116118ab57604051916118a0601f8201601f191660200184610db9565b825260203d92013e90565b634e487b7160e01b81526041600452602490fd5b505090565b6009546001600160a01b03906118dd908390831661184a565b6118e5575050565b6009541690813b15610d455760008092602460405180958193633243c79160e01b83528660048401525af190811561195a577fb0cc2628d6d644cf6be9d8110e142297ac910d6d8026d795a99f272fd9ad60b19260209261194b575b50604051908152a1565b61195490610d8f565b38611941565b6040513d6000823e3d90fdfeddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220977d4498ffc2e796f45985e7faaf53e4b11e05ce3b0a0aba493f9b74ddcc053264736f6c63430008180033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000d3c21bcecceda100000000000000000000000000000018e621b64d7808c3c47bccbbd7485d23f257d26f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000033f5dcece4505afeb69c6d0f2bf856d13b2afab8000000000000000000000000000000000000000000000000000000000000009600000000000000000000000000000000000000000000000000000000000000fa00000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000004505550530000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035055500000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _name (string): PUPS
Arg [1] : _symbol (string): PUP
Arg [2] : _initialSupply (uint256): 1000000000000000000000000
Arg [3] : _router (address): 0x18E621B64d7808c3C47bccbbD7485d23F257D26f
Arg [4] : _minimumTokenBalanceForDividendsPct (uint256): 0
Arg [5] : _teamWallet (address): 0x33F5DCECe4505aFEb69c6d0f2bf856D13B2AFAb8
Arg [6] : _teamFee (uint256): 150
Arg [7] : _dividendsFee (uint256): 250
Arg [8] : _burnFee (uint256): 100
-----Encoded View---------------
13 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000120
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000160
Arg [2] : 00000000000000000000000000000000000000000000d3c21bcecceda1000000
Arg [3] : 00000000000000000000000018e621b64d7808c3c47bccbbd7485d23f257d26f
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [5] : 00000000000000000000000033f5dcece4505afeb69c6d0f2bf856d13b2afab8
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000096
Arg [7] : 00000000000000000000000000000000000000000000000000000000000000fa
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000064
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [10] : 5055505300000000000000000000000000000000000000000000000000000000
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [12] : 5055500000000000000000000000000000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.