Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- DividendTracker
- Optimization enabled
- true
- Compiler version
- v0.8.20+commit.a1b79de6
- Optimization runs
- 1
- EVM Version
- paris
- Verified at
- 2024-05-28T07:05:03.602677Z
Constructor Arguments
0x00000000000000000000000029e3dbe974487f6a68ad4b4dab14c16b64cea7950000000000000000000000000000000000000000000000000de0b6b3a7640000
Arg [0] (address) : 0x29e3dbe974487f6a68ad4b4dab14c16b64cea795
Arg [1] (uint256) : 1000000000000000000
contracts/DividendTracker.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "./IterableMapping.sol";
/**
* @title SafeMathInt
* @dev Math operations with safety checks that revert on error
* @dev SafeMath adapted for int256
* Based on code of https://github.com/RequestNetwork/requestNetwork/blob/master/packages/requestNetworkSmartContracts/contracts/base/math/SafeMathInt.sol
*/
library SafeMathInt {
function mul(int256 a, int256 b) internal pure returns (int256) {
// Prevent overflow when multiplying INT256_MIN with -1
// https://github.com/RequestNetwork/requestNetwork/issues/43
require(!(a == -2 ** 255 && b == -1) && !(b == -2 ** 255 && a == -1));
int256 c = a * b;
require((b == 0) || (c / b == a));
return c;
}
function div(int256 a, int256 b) internal pure returns (int256) {
// Prevent overflow when dividing INT256_MIN by -1
// https://github.com/RequestNetwork/requestNetwork/issues/43
require(!(a == -2 ** 255 && b == -1) && (b > 0));
return a / b;
}
function sub(int256 a, int256 b) internal pure returns (int256) {
require((b >= 0 && a - b <= a) || (b < 0 && a - b > a));
return a - b;
}
function add(int256 a, int256 b) internal pure returns (int256) {
int256 c = a + b;
require((b >= 0 && c >= a) || (b < 0 && c < a));
return c;
}
function toUint256Safe(int256 a) internal pure returns (uint256) {
require(a >= 0);
return uint256(a);
}
}
/**
* @title SafeMathUint
* @dev Math operations with safety checks that revert on error
*/
library SafeMathUint {
function toInt256Safe(uint256 a) internal pure returns (int256) {
int256 b = int256(a);
require(b >= 0);
return b;
}
}
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryAdd(
uint256 a,
uint256 b
) internal pure returns (bool, uint256) {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
/**
* @dev Returns the substraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function trySub(
uint256 a,
uint256 b
) internal pure returns (bool, uint256) {
if (b > a) return (false, 0);
return (true, a - b);
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryMul(
uint256 a,
uint256 b
) internal pure returns (bool, uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryDiv(
uint256 a,
uint256 b
) internal pure returns (bool, uint256) {
if (b == 0) return (false, 0);
return (true, a / b);
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryMod(
uint256 a,
uint256 b
) internal pure returns (bool, uint256) {
if (b == 0) return (false, 0);
return (true, a % b);
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a, "SafeMath: subtraction overflow");
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) return 0;
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: division by zero");
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: modulo by zero");
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
require(b <= a, errorMessage);
return a - b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryDiv}.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a % b;
}
}
interface DividendPayingTokenOptionalInterface {
/// @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
) external view returns (uint256);
/// @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
) external view returns (uint256);
/// @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
) external view returns (uint256);
}
/// @title Dividend-Paying Token Interface
/// @author Roger Wu (https://github.com/roger-wu)
/// @dev An interface for a dividend-paying token contract.
interface DividendPayingTokenInterface {
/// @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 dividendOf(address _owner) external view returns (uint256);
/// @notice Withdraws the ether distributed to the sender.
/// @dev SHOULD transfer `dividendOf(msg.sender)` wei to `msg.sender`, and `dividendOf(msg.sender)` SHOULD be 0 after the transfer.
/// MUST emit a `DividendWithdrawn` event if the amount of ether transferred is greater than 0.
function withdrawDividend() external;
/// @dev This event MUST emit when ether is distributed to token holders.
/// @param from The address which sends ether to this contract.
/// @param weiAmount The amount of distributed ether in wei.
event DividendsDistributed(address indexed from, uint256 weiAmount);
/// @dev This event MUST emit when an address withdraws their dividend.
/// @param to The address which withdraws ether from this contract.
/// @param weiAmount The amount of withdrawn ether in wei.
event DividendWithdrawn(address indexed to, uint256 weiAmount);
}
contract DividendPayingToken is
ERC20,
Ownable,
DividendPayingTokenInterface,
DividendPayingTokenOptionalInterface
{
using SafeMath for uint256;
using SafeMathUint for uint256;
using SafeMathInt for int256;
address public rewardsToken;
uint256 internal constant magnitude = 2 ** 128;
uint256 internal magnifiedDividendPerShare;
mapping(address => int256) internal magnifiedDividendCorrections;
mapping(address => uint256) internal withdrawnDividends;
uint256 public totalDividendsDistributed;
constructor(
string memory _name,
string memory _symbol,
address _rewardsToken
) ERC20(_name, _symbol) {
rewardsToken = _rewardsToken;
}
function distributeDividends(uint256 amount) external onlyOwner {
require(totalSupply() > 0);
if (amount > 0) {
magnifiedDividendPerShare = magnifiedDividendPerShare.add(
(amount).mul(magnitude) / totalSupply()
);
emit DividendsDistributed(msg.sender, amount);
totalDividendsDistributed = totalDividendsDistributed.add(amount);
}
}
/// @notice Withdraws the ether distributed to the sender.
/// @dev It emits a `DividendWithdrawn` event if the amount of withdrawn ether is greater than 0.
function withdrawDividend() public virtual override {
_withdrawDividendOfUser(payable(msg.sender));
}
/// @notice Withdraws the ether distributed to the sender.
/// @dev It emits a `DividendWithdrawn` event if the amount of withdrawn ether is greater than 0.
function _withdrawDividendOfUser(
address payable user
) internal returns (uint256) {
uint256 _withdrawableDividend = withdrawableDividendOf(user);
if (_withdrawableDividend > 0) {
withdrawnDividends[user] = withdrawnDividends[user].add(
_withdrawableDividend
);
emit DividendWithdrawn(user, _withdrawableDividend);
bool success = IERC20(rewardsToken).transfer(
user,
_withdrawableDividend
);
if (!success) {
withdrawnDividends[user] = withdrawnDividends[user].sub(
_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 dividendOf(address _owner) public view override returns (uint256) {
return withdrawableDividendOf(_owner);
}
/// @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 override returns (uint256) {
return accumulativeDividendOf(_owner).sub(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 override 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)
/// = (magnifiedDividendPerShare * balanceOf(_owner) + magnifiedDividendCorrections[_owner]) / magnitude
/// @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 override returns (uint256) {
return
magnifiedDividendPerShare
.mul(balanceOf(_owner))
.toInt256Safe()
.add(magnifiedDividendCorrections[_owner])
.toUint256Safe() / magnitude;
}
/// @dev Internal function that transfer tokens from one address to another.
/// Update magnifiedDividendCorrections to keep dividends unchanged.
/// @param from The address to transfer from.
/// @param to The address to transfer to.
/// @param value The amount to be transferred.
function _transfer(
address from,
address to,
uint256 value
) internal virtual override {
require(false);
int256 _magCorrection = magnifiedDividendPerShare
.mul(value)
.toInt256Safe();
magnifiedDividendCorrections[from] = magnifiedDividendCorrections[from]
.add(_magCorrection);
magnifiedDividendCorrections[to] = magnifiedDividendCorrections[to].sub(
_magCorrection
);
}
/// @dev Internal function that mints tokens to an account.
/// Update magnifiedDividendCorrections to keep dividends unchanged.
/// @param account The account that will receive the created tokens.
/// @param value The amount that will be created.
function _mint(address account, uint256 value) internal override {
super._mint(account, value);
magnifiedDividendCorrections[account] = magnifiedDividendCorrections[
account
].sub((magnifiedDividendPerShare.mul(value)).toInt256Safe());
}
/// @dev Internal function that burns an amount of the token of a given account.
/// Update magnifiedDividendCorrections to keep dividends unchanged.
/// @param account The account whose tokens will be burnt.
/// @param value The amount that will be burnt.
function _burn(address account, uint256 value) internal override {
super._burn(account, value);
magnifiedDividendCorrections[account] = magnifiedDividendCorrections[
account
].add((magnifiedDividendPerShare.mul(value)).toInt256Safe());
}
function _setBalance(address account, uint256 newBalance) internal {
uint256 currentBalance = balanceOf(account);
if (newBalance > currentBalance) {
uint256 mintAmount = newBalance.sub(currentBalance);
_mint(account, mintAmount);
} else if (newBalance < currentBalance) {
uint256 burnAmount = currentBalance.sub(newBalance);
_burn(account, burnAmount);
}
}
}
/*
@title Dividend-Paying Token Interface
@author Roger Wu (https://github.com/roger-wu)
@dev An interface for a dividend-paying token contract.
*/
interface IDividendPayingToken {
/// @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 dividendOf(address _owner) external view returns (uint256);
/// @notice Distributes ether to token holders as dividends.
/// @dev SHOULD distribute the paid ether to token holders as dividends.
/// SHOULD NOT directly transfer ether to token holders in this function.
/// MUST emit a `DividendsDistributed` event when the amount of distributed ether is greater than 0.
function distributeDividends() external payable;
/// @notice Withdraws the ether distributed to the sender.
/// @dev SHOULD transfer `dividendOf(msg.sender)` wei to `msg.sender`, and `dividendOf(msg.sender)` SHOULD be 0 after the transfer.
/// MUST emit a `DividendWithdrawn` event if the amount of ether transferred is greater than 0.
function withdrawDividend() external;
/// @dev This event MUST emit when ether is distributed to token holders.
/// @param from The address which sends ether to this contract.
/// @param weiAmount The amount of distributed ether in wei.
event DividendsDistributed(address indexed from, uint256 weiAmount);
/// @dev This event MUST emit when an address withdraws their dividend.
/// @param to The address which withdraws ether from this contract.
/// @param weiAmount The amount of withdrawn ether in wei.
event DividendWithdrawn(address indexed to, uint256 weiAmount);
}
contract DividendTracker is Ownable, DividendPayingToken {
using SafeMath for uint256;
using SafeMathInt for int256;
using IterableMapping for IterableMapping.Map;
IterableMapping.Map private tokenHoldersMap;
uint256 public lastProcessedIndex;
mapping(address => bool) public excludedFromDividends;
mapping(address => uint256) public lastClaimTimes;
uint256 public claimWait;
uint256 public minimumTokenBalanceForDividends;
event ExcludeFromDividends(address indexed account);
event ClaimWaitUpdated(uint256 indexed newValue, uint256 indexed oldValue);
event Claim(
address indexed account,
uint256 amount,
bool indexed automatic
);
constructor(
address tokenAddress,
uint256 _minimumTokenBalanceForDividends
) DividendPayingToken("Dividen_Tracker", "Dividen_Tracker", tokenAddress) {
claimWait = 3600;
minimumTokenBalanceForDividends = _minimumTokenBalanceForDividends;
transferOwnership(msg.sender);
}
function _transfer(address, address, uint256) internal pure override {
require(false, "Dividend_Tracker: No transfers allowed");
}
function withdrawDividend() public pure override {
require(
false,
"Dividend_Tracker: withdrawDividend disabled. Use the 'claim' function on the main Dividend_Tracker contract."
);
}
function excludeFromDividends(address account) external onlyOwner {
require(!excludedFromDividends[account]);
excludedFromDividends[account] = true;
_setBalance(account, 0);
tokenHoldersMap.remove(account);
emit ExcludeFromDividends(account);
}
function updateClaimWait(uint256 newClaimWait) external onlyOwner {
require(
newClaimWait >= 3600 && newClaimWait <= 86400,
"Dividend_Tracker: claimWait must be updated to between 1 and 24 hours"
);
require(
newClaimWait != claimWait,
"Dividend_Tracker: Cannot update claimWait to same value"
);
emit ClaimWaitUpdated(newClaimWait, claimWait);
claimWait = newClaimWait;
}
function getLastProcessedIndex() external view returns (uint256) {
return lastProcessedIndex;
}
function getNumberOfTokenHolders() external view returns (uint256) {
return tokenHoldersMap.keys.length;
}
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.sub(
int256(lastProcessedIndex)
);
} else {
uint256 processesUntilEndOfArray = tokenHoldersMap.keys.length >
lastProcessedIndex
? tokenHoldersMap.keys.length.sub(lastProcessedIndex)
: 0;
iterationsUntilProcessed = index.add(
int256(processesUntilEndOfArray)
);
}
}
withdrawableDividends = withdrawableDividendOf(account);
totalDividends = accumulativeDividendOf(account);
lastClaimTime = lastClaimTimes[account];
nextClaimTime = lastClaimTime > 0 ? lastClaimTime.add(claimWait) : 0;
secondsUntilAutoClaimAvailable = nextClaimTime > block.timestamp
? nextClaimTime.sub(block.timestamp)
: 0;
}
function getAccountAtIndex(
uint256 index
)
public
view
returns (
address,
int256,
int256,
uint256,
uint256,
uint256,
uint256,
uint256
)
{
if (index >= tokenHoldersMap.size()) {
return (
0x0000000000000000000000000000000000000000,
-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.sub(lastClaimTime) >= claimWait;
}
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 process(uint256 gas) external 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.add(gasLeft.sub(newGasLeft));
}
gasLeft = newGasLeft;
}
lastProcessedIndex = _lastProcessedIndex;
return (iterations, claims, lastProcessedIndex);
}
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;
}
}
@openzeppelin/contracts/access/Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. 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 {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
@openzeppelin/contracts/token/ERC20/ERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)
pragma solidity ^0.8.0;
import "./IERC20.sol";
import "./extensions/IERC20Metadata.sol";
import "../../utils/Context.sol";
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
* For a generic mechanism see {ERC20PresetMinterPauser}.
*
* TIP: For a detailed writeup see our guide
* https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* 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.
*
* Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
* functions have been added to mitigate the well-known issues around setting
* allowances. See {IERC20-approve}.
*/
contract ERC20 is Context, IERC20, IERC20Metadata {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
/**
* @dev Sets the values for {name} and {symbol}.
*
* All two of these values are immutable: they can only be set once during
* construction.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5.05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the 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 override returns (uint8) {
return 18;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/
function transfer(address to, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_transfer(owner, to, amount);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
* `transferFrom`. This is semantically equivalent to an infinite approval.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_approve(owner, spender, amount);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20}.
*
* NOTE: Does not update the allowance if the current allowance
* is the maximum `uint256`.
*
* Requirements:
*
* - `from` and `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
* - the caller must have allowance for ``from``'s tokens of at least
* `amount`.
*/
function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, amount);
_transfer(from, to, amount);
return true;
}
/**
* @dev Atomically increases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, allowance(owner, spender) + addedValue);
return true;
}
/**
* @dev Atomically decreases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
address owner = _msgSender();
uint256 currentAllowance = allowance(owner, spender);
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(owner, spender, currentAllowance - subtractedValue);
}
return true;
}
/**
* @dev Moves `amount` of tokens from `from` to `to`.
*
* This internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
*/
function _transfer(address from, address to, uint256 amount) internal virtual {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(from, to, amount);
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
// Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by
// decrementing then incrementing.
_balances[to] += amount;
}
emit Transfer(from, to, amount);
_afterTokenTransfer(from, to, amount);
}
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply += amount;
unchecked {
// Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.
_balances[account] += amount;
}
emit Transfer(address(0), account, amount);
_afterTokenTransfer(address(0), account, amount);
}
/**
* @dev Destroys `amount` tokens from `account`, reducing the
* total supply.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
unchecked {
_balances[account] = accountBalance - amount;
// Overflow not possible: amount <= accountBalance <= totalSupply.
_totalSupply -= amount;
}
emit Transfer(account, address(0), amount);
_afterTokenTransfer(account, address(0), amount);
}
/**
* @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*/
function _approve(address owner, address spender, uint256 amount) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
/**
* @dev Updates `owner` s allowance for `spender` based on spent `amount`.
*
* Does not update the allowance amount in case of infinite allowance.
* Revert if not enough allowance is available.
*
* Might emit an {Approval} event.
*/
function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
require(currentAllowance >= amount, "ERC20: insufficient allowance");
unchecked {
_approve(owner, spender, currentAllowance - amount);
}
}
}
/**
* @dev Hook that is called before any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}
/**
* @dev Hook that is called after any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* has been transferred to `to`.
* - when `from` is zero, `amount` tokens have been minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens have been burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}
}
@openzeppelin/contracts/token/ERC20/IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}
@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*
* _Available since v4.1._
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}
@openzeppelin/contracts/utils/Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
contracts/IterableMapping.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;
library IterableMapping {
// Iterable mapping from address to uint;
struct Map {
address[] keys;
mapping(address => uint256) values;
mapping(address => uint256) indexOf;
mapping(address => bool) inserted;
}
function get(Map storage map, address key) public view returns (uint256) {
return map.values[key];
}
function getIndexOfKey(Map storage map, address key)
public
view
returns (int256)
{
if (!map.inserted[key]) {
return -1;
}
return int256(map.indexOf[key]);
}
function getKeyAtIndex(Map storage map, uint256 index)
public
view
returns (address)
{
return map.keys[index];
}
function size(Map storage map) public view returns (uint256) {
return map.keys.length;
}
function set(
Map storage map,
address key,
uint256 val
) public {
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) public {
if (!map.inserted[key]) {
return;
}
delete map.inserted[key];
delete map.values[key];
uint256 index = map.indexOf[key];
uint256 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();
}
}
Compiler Settings
{"outputSelection":{"*":{"*":["*"],"":["*"]}},"optimizer":{"runs":1,"enabled":true},"libraries":{"contracts/IterableMapping.sol":{"IterableMapping":"0x16f4941c8c2c4ca62b3f1f2b721753bd32ff4329"}},"evmVersion":"paris"}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"tokenAddress","internalType":"address"},{"type":"uint256","name":"_minimumTokenBalanceForDividends","internalType":"uint256"}]},{"type":"event","name":"Approval","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":true},{"type":"address","name":"spender","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Claim","inputs":[{"type":"address","name":"account","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"bool","name":"automatic","internalType":"bool","indexed":true}],"anonymous":false},{"type":"event","name":"ClaimWaitUpdated","inputs":[{"type":"uint256","name":"newValue","internalType":"uint256","indexed":true},{"type":"uint256","name":"oldValue","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"event","name":"DividendWithdrawn","inputs":[{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"uint256","name":"weiAmount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"DividendsDistributed","inputs":[{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"uint256","name":"weiAmount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"ExcludeFromDividends","inputs":[{"type":"address","name":"account","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"accumulativeDividendOf","inputs":[{"type":"address","name":"_owner","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"allowance","inputs":[{"type":"address","name":"owner","internalType":"address"},{"type":"address","name":"spender","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"approve","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"claimWait","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"decimals","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"decreaseAllowance","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"subtractedValue","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"distributeDividends","inputs":[{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"dividendOf","inputs":[{"type":"address","name":"_owner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"excludeFromDividends","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"excludedFromDividends","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"account","internalType":"address"},{"type":"int256","name":"index","internalType":"int256"},{"type":"int256","name":"iterationsUntilProcessed","internalType":"int256"},{"type":"uint256","name":"withdrawableDividends","internalType":"uint256"},{"type":"uint256","name":"totalDividends","internalType":"uint256"},{"type":"uint256","name":"lastClaimTime","internalType":"uint256"},{"type":"uint256","name":"nextClaimTime","internalType":"uint256"},{"type":"uint256","name":"secondsUntilAutoClaimAvailable","internalType":"uint256"}],"name":"getAccount","inputs":[{"type":"address","name":"_account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"},{"type":"int256","name":"","internalType":"int256"},{"type":"int256","name":"","internalType":"int256"},{"type":"uint256","name":"","internalType":"uint256"},{"type":"uint256","name":"","internalType":"uint256"},{"type":"uint256","name":"","internalType":"uint256"},{"type":"uint256","name":"","internalType":"uint256"},{"type":"uint256","name":"","internalType":"uint256"}],"name":"getAccountAtIndex","inputs":[{"type":"uint256","name":"index","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getLastProcessedIndex","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getNumberOfTokenHolders","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"increaseAllowance","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"addedValue","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lastClaimTimes","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lastProcessedIndex","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"minimumTokenBalanceForDividends","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"name","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"","internalType":"uint256"},{"type":"uint256","name":"","internalType":"uint256"},{"type":"uint256","name":"","internalType":"uint256"}],"name":"process","inputs":[{"type":"uint256","name":"gas","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"processAccount","inputs":[{"type":"address","name":"account","internalType":"address payable"},{"type":"bool","name":"automatic","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"rewardsToken","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setBalance","inputs":[{"type":"address","name":"account","internalType":"address payable"},{"type":"uint256","name":"newBalance","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"symbol","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalDividendsDistributed","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalSupply","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transfer","inputs":[{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transferFrom","inputs":[{"type":"address","name":"from","internalType":"address"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateClaimWait","inputs":[{"type":"uint256","name":"newClaimWait","internalType":"uint256"}]},{"type":"function","stateMutability":"pure","outputs":[],"name":"withdrawDividend","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"withdrawableDividendOf","inputs":[{"type":"address","name":"_owner","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"withdrawnDividendOf","inputs":[{"type":"address","name":"_owner","internalType":"address"}]}]
Contract Creation Code
0x60806040523480156200001157600080fd5b506040516200212338038062002123833981016040819052620000349162000221565b604080518082018252600f8082526e2234bb34b232b72faa3930b1b5b2b960891b60208084018290528451808601909552918452908301529083828260036200007e838262000302565b5060046200008d828262000302565b505050620000aa620000a4620000ea60201b60201c565b620000ee565b600680546001600160a01b0319166001600160a01b03929092169190911790555050610e106012556013819055620000e23362000140565b5050620003ce565b3390565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6200014a620001c3565b6001600160a01b038116620001b55760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b620001c081620000ee565b50565b6005546001600160a01b031633146200021f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620001ac565b565b600080604083850312156200023557600080fd5b82516001600160a01b03811681146200024d57600080fd5b6020939093015192949293505050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200028857607f821691505b602082108103620002a957634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620002fd57600081815260208120601f850160051c81016020861015620002d85750805b601f850160051c820191505b81811015620002f957828155600101620002e4565b5050505b505050565b81516001600160401b038111156200031e576200031e6200025d565b62000336816200032f845462000273565b84620002af565b602080601f8311600181146200036e5760008415620003555750858301515b600019600386901b1c1916600185901b178555620002f9565b600085815260208120601f198616915b828110156200039f578886015182559484019460019091019084016200037e565b5085821015620003be5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b611d4580620003de6000396000f3fe608060405234801561001057600080fd5b50600436106101ac5760003560e01c806306fdde03146101b1578063095ea7b3146101cf57806309bbedde146101f257806318160ddd14610204578063226cfa3d1461020c57806323b872dd1461022c57806327ce01471461023f5780633009a60914610252578063313ce5671461025b57806331e79db01461026a5780633243c7911461027f57806339509351146102925780634e7b827f146102a55780635183d6fd146102c85780636a474002146103205780636f2789ec1461032857806370a0823114610331578063715018a61461034457806385a6b3ae1461034c5780638da5cb5b1461035557806391b89fba1461037557806395d89b4114610388578063a457c2d714610390578063a8b9d240146103a3578063a9059cbb146103b6578063aafd847a146103c9578063bc4c4b37146103f2578063be10b61414610405578063d1af0c7d1461040e578063dd62ed3e14610421578063e30443bc14610434578063e7841ec014610447578063e98030c71461044f578063f2fde38b14610462578063fbcbc0f114610475578063ffb2c47914610488575b600080fd5b6101b96104b6565b6040516101c691906119e4565b60405180910390f35b6101e26101dd366004611a47565b610548565b60405190151581526020016101c6565b600b545b6040519081526020016101c6565b6002546101f6565b6101f661021a366004611a73565b60116020526000908152604090205481565b6101e261023a366004611a90565b610562565b6101f661024d366004611a73565b610586565b6101f6600f5481565b604051601281526020016101c6565b61027d610278366004611a73565b6105df565b005b61027d61028d366004611ad1565b6106dc565b6101e26102a0366004611a47565b610778565b6101e26102b3366004611a73565b60106020526000908152604090205460ff1681565b6102db6102d6366004611ad1565b61079a565b604080516001600160a01b0390991689526020890197909752958701949094526060860192909252608085015260a084015260c083015260e0820152610100016101c6565b61027d6108ee565b6101f660125481565b6101f661033f366004611a73565b61099e565b61027d6109b9565b6101f6600a5481565b61035d6109cb565b6040516001600160a01b0390911681526020016101c6565b6101f6610383366004611a73565b6109da565b6101b96109e5565b6101e261039e366004611a47565b6109f4565b6101f66103b1366004611a73565b610a6f565b6101e26103c4366004611a47565b610a9b565b6101f66103d7366004611a73565b6001600160a01b031660009081526009602052604090205490565b6101e2610400366004611af8565b610aa9565b6101f660135481565b60065461035d906001600160a01b031681565b6101f661042f366004611b31565b610b34565b61027d610442366004611a47565b610b5f565b600f546101f6565b61027d61045d366004611ad1565b610c9f565b61027d610470366004611a73565b610de0565b6102db610483366004611a73565b610e56565b61049b610496366004611ad1565b610fb7565b604080519384526020840192909252908201526060016101c6565b6060600380546104c590611b5f565b80601f01602080910402602001604051908101604052809291908181526020018280546104f190611b5f565b801561053e5780601f106105135761010080835404028352916020019161053e565b820191906000526020600020905b81548152906001019060200180831161052157829003601f168201915b5050505050905090565b6000336105568185856110d4565b60019150505b92915050565b6000336105708582856111f8565b61057b858585611272565b506001949350505050565b6001600160a01b038116600090815260086020526040812054600160801b906105d5906105d0906105ca6105c56105bc8861099e565b600754906112c9565b611352565b90611362565b6113a0565b61055c9190611baf565b6105e76113b3565b6001600160a01b03811660009081526010602052604090205460ff161561060d57600080fd5b6001600160a01b0381166000908152601060205260408120805460ff1916600117905561063b908290611412565b60405163131836e760e21b81527316f4941c8c2c4ca62b3f1f2b721753bd32ff432990634c60db9c9061067590600b908590600401611bd1565b60006040518083038186803b15801561068d57600080fd5b505af41580156106a1573d6000803e3d6000fd5b50506040516001600160a01b03841692507fa878b31040b2e6d0a9a3d3361209db3908ba62014b0dca52adbaee451d128b259150600090a250565b6106e46113b3565b60006106ef60025490565b116106f957600080fd5b80156107755761072c61070b60025490565b61071983600160801b6112c9565b6107239190611baf565b60075490611465565b60075560405181815233907fa493a9229478c3fcd73f66d2cdeb7f94fd0f341da924d1054236d784541165119060200160405180910390a2600a546107719082611465565b600a555b50565b60003361055681858561078b8383610b34565b6107959190611be8565b6110d4565b600080600080600080600080600b7316f4941c8c2c4ca62b3f1f2b721753bd32ff432963deb3d89690916040518263ffffffff1660e01b81526004016107e291815260200190565b602060405180830381865af41580156107ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108239190611bfb565b89106108485750600096506000199550859450869350839250829150819050806108e3565b6040516368d54f3f60e11b8152600b6004820152602481018a90526000907316f4941c8c2c4ca62b3f1f2b721753bd32ff43299063d1aa9e7e90604401602060405180830381865af41580156108a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c69190611c14565b90506108d181610e56565b98509850985098509850985098509850505b919395975091939597565b60405162461bcd60e51b815260206004820152606c60248201527f4469766964656e645f547261636b65723a20776974686472617744697669646560448201527f6e642064697361626c65642e20557365207468652027636c61696d272066756e60648201527f6374696f6e206f6e20746865206d61696e204469766964656e645f547261636b60848201526b32b91031b7b73a3930b1ba1760a11b60a482015260c4015b60405180910390fd5b565b6001600160a01b031660009081526020819052604090205490565b6109c16113b3565b61099c60006114c2565b6005546001600160a01b031690565b600061055c82610a6f565b6060600480546104c590611b5f565b60003381610a028286610b34565b905083811015610a625760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610993565b61057b82868684036110d4565b6001600160a01b03811660009081526009602052604081205461055c90610a9584610586565b90611514565b600033610556818585611272565b6000610ab36113b3565b6000610abe84611570565b90508015610b2a576001600160a01b038416600081815260116020526040908190204290555184151591907fa2c38e2d2fb7e3e1912d937fd1ca11ed6d51864dee4cfa7a7bf02becd7acf09290610b189085815260200190565b60405180910390a3600191505061055c565b5060009392505050565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b610b676113b3565b6001600160a01b03821660009081526010602052604090205460ff16610c9b576013548110610c1857610b9a8282611412565b604051632f0ad01760e21b8152600b60048201526001600160a01b0383166024820152604481018290527316f4941c8c2c4ca62b3f1f2b721753bd32ff43299063bc2b405c9060640160006040518083038186803b158015610bfb57600080fd5b505af4158015610c0f573d6000803e3d6000fd5b50505050610c8e565b610c23826000611412565b60405163131836e760e21b81527316f4941c8c2c4ca62b3f1f2b721753bd32ff432990634c60db9c90610c5d90600b908690600401611bd1565b60006040518083038186803b158015610c7557600080fd5b505af4158015610c89573d6000803e3d6000fd5b505050505b610c99826001610aa9565b505b5050565b610ca76113b3565b610e108110158015610cbc5750620151808111155b610d3c5760405162461bcd60e51b815260206004820152604560248201527f4469766964656e645f547261636b65723a20636c61696d57616974206d75737460448201527f206265207570646174656420746f206265747765656e203120616e6420323420606482015264686f75727360d81b608482015260a401610993565b6012548103610dad5760405162461bcd60e51b815260206004820152603760248201527f4469766964656e645f547261636b65723a2043616e6e6f742075706461746520604482015276636c61696d5761697420746f2073616d652076616c756560481b6064820152608401610993565b60125460405182907f474ea64804364a1e29a4487ddb63c3342a2dd826ccd8acf48825e680a0e6f20f90600090a3601255565b610de86113b3565b6001600160a01b038116610e4d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610993565b610775816114c2565b600080600080600080600080889750600b7316f4941c8c2c4ca62b3f1f2b721753bd32ff43296317e142d190918a6040518363ffffffff1660e01b8152600401610ea1929190611bd1565b602060405180830381865af4158015610ebe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ee29190611bfb565b9650600019955060008712610f4457600f54871115610f1057600f54610f099088906116d5565b9550610f44565b600f54600b5460009110610f25576000610f34565b600f54600b54610f3491611514565b9050610f408882611362565b9650505b610f4d88610a6f565b9450610f5888610586565b6001600160a01b038916600090815260116020526040902054909450925082610f82576000610f90565b601254610f90908490611465565b9150428211610fa0576000610faa565b610faa8242611514565b9050919395975091939597565b600b5460009081908190808203610fd9575050600f54600092508291506110cd565b600f546000805a90506000805b8984108015610ff457508582105b156110bc578461100381611c31565b600b549096508610905061101657600094505b6000600b600001868154811061102e5761102e611c4a565b60009182526020808320909101546001600160a01b0316808352601190915260409091205490915061105f90611721565b156110825761106f816001610aa9565b15611082578161107e81611c31565b9250505b8261108c81611c31565b93505060005a9050808511156110b3576110b06110a98683611514565b8790611465565b95505b9350610fe69050565b600f85905590975095509193505050505b9193909250565b6001600160a01b0383166111365760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610993565b6001600160a01b0382166111975760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610993565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b60006112048484610b34565b9050600019811461126c578181101561125f5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610993565b61126c84848484036110d4565b50505050565b60405162461bcd60e51b815260206004820152602660248201527f4469766964656e645f547261636b65723a204e6f207472616e736665727320616044820152651b1b1bddd95960d21b6064820152608401610993565b6000826000036112db5750600061055c565b60006112e78385611c60565b9050826112f48583611baf565b1461134b5760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b6064820152608401610993565b9392505050565b6000818181121561055c57600080fd5b60008061136f8385611c77565b9050600083121580156113825750838112155b80611397575060008312801561139757508381125b61134b57600080fd5b6000808212156113af57600080fd5b5090565b336113bc6109cb565b6001600160a01b03161461099c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610993565b600061141d8361099e565b9050808211156114455760006114338383611514565b905061143f8482611748565b50610c99565b80821015610c995760006114598284611514565b905061126c84826117ac565b6000806114728385611be8565b90508381101561134b5760405162461bcd60e51b815260206004820152601b60248201527a536166654d6174683a206164646974696f6e206f766572666c6f7760281b6044820152606401610993565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000828211156115665760405162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f7700006044820152606401610993565b61134b8284611c9f565b60008061157c83610a6f565b905080156116cc576001600160a01b0383166000908152600960205260409020546115a79082611465565b6001600160a01b038416600081815260096020526040908190209290925590517fee503bee2bb6a87e57bc57db795f98137327401a0e7b7ce42e37926cc1a9ca4d906115f69084815260200190565b60405180910390a260065460405163a9059cbb60e01b81526001600160a01b03858116600483015260248201849052600092169063a9059cbb906044016020604051808303816000875af1158015611652573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116769190611cb2565b9050806116c5576001600160a01b0384166000908152600960205260409020546116a09083611514565b6001600160a01b03909416600090815260096020526040812094909455509192915050565b5092915050565b50600092915050565b60008082121580156116f05750826116ed8382611ccf565b13155b8061170e575060008212801561170e57508261170c8382611ccf565b135b61171757600080fd5b61134b8284611ccf565b60004282111561173357506000919050565b6012546117404284611514565b101592915050565b61175282826117f0565b61178c61176d6105c5836007546112c990919063ffffffff16565b6001600160a01b038416600090815260086020526040902054906116d5565b6001600160a01b0390921660009081526008602052604090209190915550565b6117b682826118b1565b61178c6117d16105c5836007546112c990919063ffffffff16565b6001600160a01b03841660009081526008602052604090205490611362565b6001600160a01b0382166118465760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610993565b61185260008383610c99565b80600260008282546118649190611be8565b90915550506001600160a01b03821660008181526020818152604080832080548601905551848152600080516020611cf0833981519152910160405180910390a3610c9b60008383610c99565b6001600160a01b0382166119115760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610993565b61191d82600083610c99565b6001600160a01b038216600090815260208190526040902054818110156119915760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610993565b6001600160a01b038316600081815260208181526040808320868603905560028054879003905551858152919291600080516020611cf0833981519152910160405180910390a3610c9983600084610c99565b600060208083528351808285015260005b81811015611a11578581018301518582016040015282016119f5565b506000604082860101526040601f19601f8301168501019250505092915050565b6001600160a01b038116811461077557600080fd5b60008060408385031215611a5a57600080fd5b8235611a6581611a32565b946020939093013593505050565b600060208284031215611a8557600080fd5b813561134b81611a32565b600080600060608486031215611aa557600080fd5b8335611ab081611a32565b92506020840135611ac081611a32565b929592945050506040919091013590565b600060208284031215611ae357600080fd5b5035919050565b801515811461077557600080fd5b60008060408385031215611b0b57600080fd5b8235611b1681611a32565b91506020830135611b2681611aea565b809150509250929050565b60008060408385031215611b4457600080fd5b8235611b4f81611a32565b91506020830135611b2681611a32565b600181811c90821680611b7357607f821691505b602082108103611b9357634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b600082611bcc57634e487b7160e01b600052601260045260246000fd5b500490565b9182526001600160a01b0316602082015260400190565b8082018082111561055c5761055c611b99565b600060208284031215611c0d57600080fd5b5051919050565b600060208284031215611c2657600080fd5b815161134b81611a32565b600060018201611c4357611c43611b99565b5060010190565b634e487b7160e01b600052603260045260246000fd5b808202811582820484141761055c5761055c611b99565b8082018281126000831280158216821582161715611c9757611c97611b99565b505092915050565b8181038181111561055c5761055c611b99565b600060208284031215611cc457600080fd5b815161134b81611aea565b81810360008312801583831316838312821617156116c5576116c5611b9956feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220fd33c440ccad24d5489e489876399b1077a6eaa4c999f47102a737187e6e77b664736f6c6343000814003300000000000000000000000029e3dbe974487f6a68ad4b4dab14c16b64cea7950000000000000000000000000000000000000000000000000de0b6b3a7640000
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106101ac5760003560e01c806306fdde03146101b1578063095ea7b3146101cf57806309bbedde146101f257806318160ddd14610204578063226cfa3d1461020c57806323b872dd1461022c57806327ce01471461023f5780633009a60914610252578063313ce5671461025b57806331e79db01461026a5780633243c7911461027f57806339509351146102925780634e7b827f146102a55780635183d6fd146102c85780636a474002146103205780636f2789ec1461032857806370a0823114610331578063715018a61461034457806385a6b3ae1461034c5780638da5cb5b1461035557806391b89fba1461037557806395d89b4114610388578063a457c2d714610390578063a8b9d240146103a3578063a9059cbb146103b6578063aafd847a146103c9578063bc4c4b37146103f2578063be10b61414610405578063d1af0c7d1461040e578063dd62ed3e14610421578063e30443bc14610434578063e7841ec014610447578063e98030c71461044f578063f2fde38b14610462578063fbcbc0f114610475578063ffb2c47914610488575b600080fd5b6101b96104b6565b6040516101c691906119e4565b60405180910390f35b6101e26101dd366004611a47565b610548565b60405190151581526020016101c6565b600b545b6040519081526020016101c6565b6002546101f6565b6101f661021a366004611a73565b60116020526000908152604090205481565b6101e261023a366004611a90565b610562565b6101f661024d366004611a73565b610586565b6101f6600f5481565b604051601281526020016101c6565b61027d610278366004611a73565b6105df565b005b61027d61028d366004611ad1565b6106dc565b6101e26102a0366004611a47565b610778565b6101e26102b3366004611a73565b60106020526000908152604090205460ff1681565b6102db6102d6366004611ad1565b61079a565b604080516001600160a01b0390991689526020890197909752958701949094526060860192909252608085015260a084015260c083015260e0820152610100016101c6565b61027d6108ee565b6101f660125481565b6101f661033f366004611a73565b61099e565b61027d6109b9565b6101f6600a5481565b61035d6109cb565b6040516001600160a01b0390911681526020016101c6565b6101f6610383366004611a73565b6109da565b6101b96109e5565b6101e261039e366004611a47565b6109f4565b6101f66103b1366004611a73565b610a6f565b6101e26103c4366004611a47565b610a9b565b6101f66103d7366004611a73565b6001600160a01b031660009081526009602052604090205490565b6101e2610400366004611af8565b610aa9565b6101f660135481565b60065461035d906001600160a01b031681565b6101f661042f366004611b31565b610b34565b61027d610442366004611a47565b610b5f565b600f546101f6565b61027d61045d366004611ad1565b610c9f565b61027d610470366004611a73565b610de0565b6102db610483366004611a73565b610e56565b61049b610496366004611ad1565b610fb7565b604080519384526020840192909252908201526060016101c6565b6060600380546104c590611b5f565b80601f01602080910402602001604051908101604052809291908181526020018280546104f190611b5f565b801561053e5780601f106105135761010080835404028352916020019161053e565b820191906000526020600020905b81548152906001019060200180831161052157829003601f168201915b5050505050905090565b6000336105568185856110d4565b60019150505b92915050565b6000336105708582856111f8565b61057b858585611272565b506001949350505050565b6001600160a01b038116600090815260086020526040812054600160801b906105d5906105d0906105ca6105c56105bc8861099e565b600754906112c9565b611352565b90611362565b6113a0565b61055c9190611baf565b6105e76113b3565b6001600160a01b03811660009081526010602052604090205460ff161561060d57600080fd5b6001600160a01b0381166000908152601060205260408120805460ff1916600117905561063b908290611412565b60405163131836e760e21b81527316f4941c8c2c4ca62b3f1f2b721753bd32ff432990634c60db9c9061067590600b908590600401611bd1565b60006040518083038186803b15801561068d57600080fd5b505af41580156106a1573d6000803e3d6000fd5b50506040516001600160a01b03841692507fa878b31040b2e6d0a9a3d3361209db3908ba62014b0dca52adbaee451d128b259150600090a250565b6106e46113b3565b60006106ef60025490565b116106f957600080fd5b80156107755761072c61070b60025490565b61071983600160801b6112c9565b6107239190611baf565b60075490611465565b60075560405181815233907fa493a9229478c3fcd73f66d2cdeb7f94fd0f341da924d1054236d784541165119060200160405180910390a2600a546107719082611465565b600a555b50565b60003361055681858561078b8383610b34565b6107959190611be8565b6110d4565b600080600080600080600080600b7316f4941c8c2c4ca62b3f1f2b721753bd32ff432963deb3d89690916040518263ffffffff1660e01b81526004016107e291815260200190565b602060405180830381865af41580156107ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108239190611bfb565b89106108485750600096506000199550859450869350839250829150819050806108e3565b6040516368d54f3f60e11b8152600b6004820152602481018a90526000907316f4941c8c2c4ca62b3f1f2b721753bd32ff43299063d1aa9e7e90604401602060405180830381865af41580156108a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c69190611c14565b90506108d181610e56565b98509850985098509850985098509850505b919395975091939597565b60405162461bcd60e51b815260206004820152606c60248201527f4469766964656e645f547261636b65723a20776974686472617744697669646560448201527f6e642064697361626c65642e20557365207468652027636c61696d272066756e60648201527f6374696f6e206f6e20746865206d61696e204469766964656e645f547261636b60848201526b32b91031b7b73a3930b1ba1760a11b60a482015260c4015b60405180910390fd5b565b6001600160a01b031660009081526020819052604090205490565b6109c16113b3565b61099c60006114c2565b6005546001600160a01b031690565b600061055c82610a6f565b6060600480546104c590611b5f565b60003381610a028286610b34565b905083811015610a625760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610993565b61057b82868684036110d4565b6001600160a01b03811660009081526009602052604081205461055c90610a9584610586565b90611514565b600033610556818585611272565b6000610ab36113b3565b6000610abe84611570565b90508015610b2a576001600160a01b038416600081815260116020526040908190204290555184151591907fa2c38e2d2fb7e3e1912d937fd1ca11ed6d51864dee4cfa7a7bf02becd7acf09290610b189085815260200190565b60405180910390a3600191505061055c565b5060009392505050565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b610b676113b3565b6001600160a01b03821660009081526010602052604090205460ff16610c9b576013548110610c1857610b9a8282611412565b604051632f0ad01760e21b8152600b60048201526001600160a01b0383166024820152604481018290527316f4941c8c2c4ca62b3f1f2b721753bd32ff43299063bc2b405c9060640160006040518083038186803b158015610bfb57600080fd5b505af4158015610c0f573d6000803e3d6000fd5b50505050610c8e565b610c23826000611412565b60405163131836e760e21b81527316f4941c8c2c4ca62b3f1f2b721753bd32ff432990634c60db9c90610c5d90600b908690600401611bd1565b60006040518083038186803b158015610c7557600080fd5b505af4158015610c89573d6000803e3d6000fd5b505050505b610c99826001610aa9565b505b5050565b610ca76113b3565b610e108110158015610cbc5750620151808111155b610d3c5760405162461bcd60e51b815260206004820152604560248201527f4469766964656e645f547261636b65723a20636c61696d57616974206d75737460448201527f206265207570646174656420746f206265747765656e203120616e6420323420606482015264686f75727360d81b608482015260a401610993565b6012548103610dad5760405162461bcd60e51b815260206004820152603760248201527f4469766964656e645f547261636b65723a2043616e6e6f742075706461746520604482015276636c61696d5761697420746f2073616d652076616c756560481b6064820152608401610993565b60125460405182907f474ea64804364a1e29a4487ddb63c3342a2dd826ccd8acf48825e680a0e6f20f90600090a3601255565b610de86113b3565b6001600160a01b038116610e4d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610993565b610775816114c2565b600080600080600080600080889750600b7316f4941c8c2c4ca62b3f1f2b721753bd32ff43296317e142d190918a6040518363ffffffff1660e01b8152600401610ea1929190611bd1565b602060405180830381865af4158015610ebe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ee29190611bfb565b9650600019955060008712610f4457600f54871115610f1057600f54610f099088906116d5565b9550610f44565b600f54600b5460009110610f25576000610f34565b600f54600b54610f3491611514565b9050610f408882611362565b9650505b610f4d88610a6f565b9450610f5888610586565b6001600160a01b038916600090815260116020526040902054909450925082610f82576000610f90565b601254610f90908490611465565b9150428211610fa0576000610faa565b610faa8242611514565b9050919395975091939597565b600b5460009081908190808203610fd9575050600f54600092508291506110cd565b600f546000805a90506000805b8984108015610ff457508582105b156110bc578461100381611c31565b600b549096508610905061101657600094505b6000600b600001868154811061102e5761102e611c4a565b60009182526020808320909101546001600160a01b0316808352601190915260409091205490915061105f90611721565b156110825761106f816001610aa9565b15611082578161107e81611c31565b9250505b8261108c81611c31565b93505060005a9050808511156110b3576110b06110a98683611514565b8790611465565b95505b9350610fe69050565b600f85905590975095509193505050505b9193909250565b6001600160a01b0383166111365760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610993565b6001600160a01b0382166111975760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610993565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b60006112048484610b34565b9050600019811461126c578181101561125f5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610993565b61126c84848484036110d4565b50505050565b60405162461bcd60e51b815260206004820152602660248201527f4469766964656e645f547261636b65723a204e6f207472616e736665727320616044820152651b1b1bddd95960d21b6064820152608401610993565b6000826000036112db5750600061055c565b60006112e78385611c60565b9050826112f48583611baf565b1461134b5760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b6064820152608401610993565b9392505050565b6000818181121561055c57600080fd5b60008061136f8385611c77565b9050600083121580156113825750838112155b80611397575060008312801561139757508381125b61134b57600080fd5b6000808212156113af57600080fd5b5090565b336113bc6109cb565b6001600160a01b03161461099c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610993565b600061141d8361099e565b9050808211156114455760006114338383611514565b905061143f8482611748565b50610c99565b80821015610c995760006114598284611514565b905061126c84826117ac565b6000806114728385611be8565b90508381101561134b5760405162461bcd60e51b815260206004820152601b60248201527a536166654d6174683a206164646974696f6e206f766572666c6f7760281b6044820152606401610993565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000828211156115665760405162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f7700006044820152606401610993565b61134b8284611c9f565b60008061157c83610a6f565b905080156116cc576001600160a01b0383166000908152600960205260409020546115a79082611465565b6001600160a01b038416600081815260096020526040908190209290925590517fee503bee2bb6a87e57bc57db795f98137327401a0e7b7ce42e37926cc1a9ca4d906115f69084815260200190565b60405180910390a260065460405163a9059cbb60e01b81526001600160a01b03858116600483015260248201849052600092169063a9059cbb906044016020604051808303816000875af1158015611652573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116769190611cb2565b9050806116c5576001600160a01b0384166000908152600960205260409020546116a09083611514565b6001600160a01b03909416600090815260096020526040812094909455509192915050565b5092915050565b50600092915050565b60008082121580156116f05750826116ed8382611ccf565b13155b8061170e575060008212801561170e57508261170c8382611ccf565b135b61171757600080fd5b61134b8284611ccf565b60004282111561173357506000919050565b6012546117404284611514565b101592915050565b61175282826117f0565b61178c61176d6105c5836007546112c990919063ffffffff16565b6001600160a01b038416600090815260086020526040902054906116d5565b6001600160a01b0390921660009081526008602052604090209190915550565b6117b682826118b1565b61178c6117d16105c5836007546112c990919063ffffffff16565b6001600160a01b03841660009081526008602052604090205490611362565b6001600160a01b0382166118465760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610993565b61185260008383610c99565b80600260008282546118649190611be8565b90915550506001600160a01b03821660008181526020818152604080832080548601905551848152600080516020611cf0833981519152910160405180910390a3610c9b60008383610c99565b6001600160a01b0382166119115760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610993565b61191d82600083610c99565b6001600160a01b038216600090815260208190526040902054818110156119915760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610993565b6001600160a01b038316600081815260208181526040808320868603905560028054879003905551858152919291600080516020611cf0833981519152910160405180910390a3610c9983600084610c99565b600060208083528351808285015260005b81811015611a11578581018301518582016040015282016119f5565b506000604082860101526040601f19601f8301168501019250505092915050565b6001600160a01b038116811461077557600080fd5b60008060408385031215611a5a57600080fd5b8235611a6581611a32565b946020939093013593505050565b600060208284031215611a8557600080fd5b813561134b81611a32565b600080600060608486031215611aa557600080fd5b8335611ab081611a32565b92506020840135611ac081611a32565b929592945050506040919091013590565b600060208284031215611ae357600080fd5b5035919050565b801515811461077557600080fd5b60008060408385031215611b0b57600080fd5b8235611b1681611a32565b91506020830135611b2681611aea565b809150509250929050565b60008060408385031215611b4457600080fd5b8235611b4f81611a32565b91506020830135611b2681611a32565b600181811c90821680611b7357607f821691505b602082108103611b9357634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b600082611bcc57634e487b7160e01b600052601260045260246000fd5b500490565b9182526001600160a01b0316602082015260400190565b8082018082111561055c5761055c611b99565b600060208284031215611c0d57600080fd5b5051919050565b600060208284031215611c2657600080fd5b815161134b81611a32565b600060018201611c4357611c43611b99565b5060010190565b634e487b7160e01b600052603260045260246000fd5b808202811582820484141761055c5761055c611b99565b8082018281126000831280158216821582161715611c9757611c97611b99565b505092915050565b8181038181111561055c5761055c611b99565b600060208284031215611cc457600080fd5b815161134b81611aea565b81810360008312801583831316838312821617156116c5576116c5611b9956feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220fd33c440ccad24d5489e489876399b1077a6eaa4c999f47102a737187e6e77b664736f6c63430008140033
External libraries
IterableMapping : 0x16f4941c8c2c4ca62b3f1f2b721753bd32ff4329