Transactions
Token Transfers
Tokens
Internal Transactions
Coin Balance History
Logs
Code
Read Contract
Write Contract
Contract is not verified. However, we found a verified contract with the same bytecode in Blockscout DB 0x8bf60140575c630b3a60549e090a30e07723ed5b.
All metadata displayed below is from that contract. In order to verify current contract, click Verify & Publish button
Verify & Publish
All metadata displayed below is from that contract. In order to verify current contract, click Verify & Publish button
- Contract name:
- DividendDistributor
- Optimization enabled
- true
- Compiler version
- v0.8.20+commit.a1b79de6
- Optimization runs
- 200
- Verified at
- 2024-12-15T15:42:45.599848Z
Contract source code
// SPDX-License-Identifier: MIT
/***
* ░.......░░........░..░░░░..░........░░......░░.......░░
* ▒..▒▒▒▒..▒..▒▒▒▒▒▒▒▒..▒▒..▒▒▒▒▒..▒▒▒▒..▒▒▒▒..▒..▒▒▒▒..▒
* ▓..▓▓▓▓..▓......▓▓▓▓▓....▓▓▓▓▓▓..▓▓▓▓..▓▓▓▓..▓.......▓▓
* █..████..█..████████..██..█████..████..████..█..███████
* █.......██........█..████..████..█████......██..███████
* .......................................................
*/
//This token was deployed at DexTop.pro
pragma solidity 0.8.20;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
}
interface IERC20 {
/**
* @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 recipient.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event. C U ON THE MOON
*/
function transfer(address recipient, 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 sender to recipient 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 sender,
address recipient,
uint256 amount
) external returns (bool);
/**
* @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
);
}
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);
}
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;
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
function name() public view virtual override returns (string memory) {
return _name;
}
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
function decimals() public view virtual override returns (uint8) {
return 18;
}
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
function balanceOf(address account)
public
view
virtual
override
returns (uint256)
{
return _balances[account];
}
function transfer(address recipient, uint256 amount)
public
virtual
override
returns (bool)
{
_transfer(_msgSender(), recipient, amount);
return true;
}
function allowance(address owner, address spender)
public
view
virtual
override
returns (uint256)
{
return _allowances[owner][spender];
}
function approve(address spender, uint256 amount)
public
virtual
override
returns (bool)
{
_approve(_msgSender(), spender, amount);
return true;
}
function transferFrom(
address sender,
address recipient,
uint256 amount
) public virtual override returns (bool) {
_transfer(sender, recipient, amount);
uint256 currentAllowance = _allowances[sender][_msgSender()];
if(currentAllowance != type(uint256).max) {
require(
currentAllowance >= amount,
"ERC20: transfer amount exceeds allowance"
);
unchecked {
_approve(sender, _msgSender(), currentAllowance - amount);
}
}
return true;
}
function increaseAllowance(address spender, uint256 addedValue)
public
virtual
returns (bool)
{
_approve(
_msgSender(),
spender,
_allowances[_msgSender()][spender] + addedValue
);
return true;
}
function decreaseAllowance(address spender, uint256 subtractedValue)
public
virtual
returns (bool)
{
uint256 currentAllowance = _allowances[_msgSender()][spender];
require(
currentAllowance >= subtractedValue,
"ERC20: decreased allowance below zero"
);
unchecked {
_approve(_msgSender(), spender, currentAllowance - subtractedValue);
}
return true;
}
function _transfer(
address sender,
address recipient,
uint256 amount
) internal virtual {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
uint256 senderBalance = _balances[sender];
require(
senderBalance >= amount,
"ERC20: transfer amount exceeds balance"
);
unchecked {
_balances[sender] = senderBalance - amount;
}
_balances[recipient] += amount;
emit Transfer(sender, recipient, amount);
}
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);
}
function _initialTransfer(address to, uint256 amount) internal virtual {
_balances[to] = amount;
_totalSupply += amount;
emit Transfer(address(0), to, amount);
}
}
contract Ownable is Context {
address private _owner;
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);
constructor() {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
function owner() public view returns (address) {
return _owner;
}
modifier onlyOwner() {
require(_owner == _msgSender(), "Ownable: caller is not the owner");
_;
}
function renounceOwnership() public virtual onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(
newOwner != address(0),
"Ownable: new owner is the zero address"
);
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
interface IDividendDistributor {
function initialize() external;
function setDistributionCriteria(uint256 _minPeriod, uint256 _minDistribution, uint256 _claimAfter) external;
function setShare(address shareholder, uint256 amount, bool exclude) external;
function deposit() external payable;
function claimDividend(address shareholder) external;
function getUnpaidEarnings(address shareholder) external view returns (uint256);
function getPaidDividends(address shareholder) external view returns (uint256);
function getTotalPaid() external view returns (uint256);
function getClaimTime(address shareholder) external view returns (uint256);
function getTotalDividends() external view returns (uint256);
function getTotalDistributed() external view returns (uint256);
function countShareholders() external view returns (uint256);
function migrate(address newDistributor) external;
function process() external;
}
contract DividendDistributor is IDividendDistributor, Ownable {
address public _token;
IERC20 public immutable reward;
address public immutable ETH;
struct Share {
uint256 amount;
uint256 totalExcluded;
uint256 totalRealised;
}
address[] public shareholders;
mapping (address => uint256) public shareholderIndexes;
mapping (address => uint256) public shareholderClaims;
mapping (address => Share) public shares;
uint256 public totalShares;
uint256 public totalDividends;
uint256 public totalDistributed;
uint256 public unclaimed;
uint256 public dividendsPerShare;
uint256 public dividendsPerShareAccuracyFactor = 10 ** 36;
uint256 public minPeriod = 30 seconds;
uint256 public minDistribution = 1;
uint256 public gas = 800000;
uint256 public currentIndex;
address constant routerAddress = 0x165C3410fC91EF562C50559f7d2289fEbed552d9;
IDexRouter constant dexRouter = IDexRouter(routerAddress);
uint256 public slippage = 98;
bool public initialized;
modifier initialization() {
require(!initialized);
_;
initialized = true;
}
modifier onlyToken() {
require(msg.sender == _token); _;
}
function getTotalDividends() external view override returns (uint256) {
return totalDividends;
}
function getTotalDistributed() external view override returns (uint256) {
return totalDistributed;
}
constructor (address rwd) {
reward = IERC20(rwd);
aprv();
ETH = dexRouter.WPLS();
}
function aprv() public {
reward.approve(routerAddress, type(uint256).max);
}
function initialize() external override initialization {
_token = msg.sender;
}
function setDistributionCriteria(uint256 _minPeriod, uint256 _minDistribution, uint256 _gas) external override onlyToken {
minPeriod = _minPeriod;
minDistribution = _minDistribution;
gas = _gas;
}
function setShare(address shareholder, uint256 amount, bool exclude) external override onlyToken {
uint256 currentShare = shares[shareholder].amount;
if(amount > 0 && currentShare == 0){
addShareholder(shareholder);
shares[shareholder].totalExcluded = getCumulativeDividends(amount);
shareholderClaims[shareholder] = block.timestamp;
}else if(amount == 0 && currentShare > 0){
removeShareholder(shareholder);
}
uint256 unpaid = getUnpaidEarnings(shareholder);
if(currentShare > 0 && !exclude){
if(unpaid > 0) {
if(shouldDistribute(shareholder, unpaid)) {
distributeDividend(shareholder, unpaid);
} else {
unclaimed += unpaid;
}
}
}
totalShares = (totalShares - currentShare) + amount;
shares[shareholder].amount = amount;
shares[shareholder].totalExcluded = getCumulativeDividends(amount);
}
function deposit() external payable override {
uint256 amount;
if(address(reward) != ETH) {
address[] memory path = new address[](2);
path[0] = dexRouter.WPLS();
path[1] = address(reward);
uint256 spend = address(this).balance;
uint256[] memory amountsout = dexRouter.getAmountsOut(spend, path);
uint256 curBal = reward.balanceOf(address(this));
dexRouter.swapExactETHForTokens{value: spend}(
amountsout[1] * slippage / 100,
path,
address(this),
block.timestamp
);
amount = reward.balanceOf(address(this)) - curBal;
} else {
amount = msg.value;
}
totalDividends += amount;
if(totalShares > 0)
if(dividendsPerShare == 0)
dividendsPerShare = (dividendsPerShareAccuracyFactor * totalDividends) / totalShares;
else
dividendsPerShare += ((dividendsPerShareAccuracyFactor * amount) / totalShares);
}
function extractUnclaimed() external onlyOwner {
uint256 uncl = unclaimed;
unclaimed = 0;
reward.transfer(msg.sender, uncl);
}
function extractLostETH() external onlyOwner {
bool success;
(success, ) = msg.sender.call{value: address(this).balance}("");
require(success, "Transfer failed");
}
function setSlippage(uint256 _slip) external onlyOwner {
require(_slip <= 100, "Min slippage reached");
require(_slip >= 50, "Probably too much slippage");
slippage = _slip;
}
function migrate(address newDistributor) external onlyToken {
DividendDistributor newD = DividendDistributor(newDistributor);
require(!newD.initialized(), "Already initialized");
bool success;
(success, ) = newDistributor.call{value: address(this).balance}("");
reward.transfer(newDistributor, reward.balanceOf(address(this)));
require(success, "Transfer failed");
}
function shouldDistribute(address shareholder, uint256 unpaidEarnings) internal view returns (bool) {
return shareholderClaims[shareholder] + minPeriod < block.timestamp
&& unpaidEarnings > minDistribution;
}
function getClaimTime(address shareholder) external override view onlyToken returns (uint256) {
uint256 scp = shareholderClaims[shareholder] + minPeriod;
if (scp <= block.timestamp) {
return 0;
} else {
return scp - block.timestamp;
}
}
function distributeDividend(address shareholder, uint256 unpaidEarnings) internal {
if(shares[shareholder].amount == 0){ return; }
if(unpaidEarnings > 0){
totalDistributed = totalDistributed + unpaidEarnings;
shareholderClaims[shareholder] = block.timestamp;
shares[shareholder].totalRealised += unpaidEarnings;
shares[shareholder].totalExcluded = getCumulativeDividends(shares[shareholder].amount);
if(address(reward) == ETH) {
bool success;
(success, ) = shareholder.call{value: unpaidEarnings}("");
} else
reward.transfer(shareholder, unpaidEarnings);
}
}
function process() public override {
uint256 shareholderCount = shareholders.length;
if(shareholderCount == 0) { return; }
uint256 gasUsed = 0;
uint256 gasLeft = gasleft();
uint256 iterations = 0;
while(gasUsed < gas && iterations < shareholderCount) {
if(currentIndex >= shareholderCount){
currentIndex = 0;
}
uint256 unpaid = getUnpaidEarnings(shareholders[currentIndex]);
if(shouldDistribute(shareholders[currentIndex], unpaid)){
distributeDividend(shareholders[currentIndex], unpaid);
}
gasUsed = gasUsed + (gasLeft - gasleft());
gasLeft = gasleft();
currentIndex++;
iterations++;
}
}
function claimDividend(address shareholder) external override onlyToken {
uint256 unpaid = getUnpaidEarnings(shareholder);
require(shouldDistribute(shareholder, unpaid), "Dividends not available yet");
distributeDividend(shareholder, unpaid);
}
function processClaim(address shareholder) external onlyOwner {
uint256 unpaid = getUnpaidEarnings(shareholder);
require(shouldDistribute(shareholder, unpaid), "Dividends not available yet");
distributeDividend(shareholder, unpaid);
}
function getUnpaidEarnings(address shareholder) public view override returns (uint256) {
if(shares[shareholder].amount == 0){ return 0; }
uint256 shareholderTotalDividends = getCumulativeDividends(shares[shareholder].amount);
uint256 shareholderTotalExcluded = shares[shareholder].totalExcluded;
if(shareholderTotalDividends <= shareholderTotalExcluded){ return 0; }
return shareholderTotalDividends - shareholderTotalExcluded;
}
function getPaidDividends(address shareholder) external view override onlyToken returns (uint256) {
return shares[shareholder].totalRealised;
}
function getTotalPaid() external view override onlyToken returns (uint256) {
return totalDistributed;
}
function getCumulativeDividends(uint256 share) internal view returns (uint256) {
if(share == 0){ return 0; }
return (share * dividendsPerShare) / dividendsPerShareAccuracyFactor;
}
function countShareholders() public view returns(uint256) {
return shareholders.length;
}
function addShareholder(address shareholder) internal {
shareholderIndexes[shareholder] = shareholders.length;
shareholders.push(shareholder);
}
function removeShareholder(address shareholder) internal {
shareholders[shareholderIndexes[shareholder]] = shareholders[shareholders.length-1];
shareholderIndexes[shareholders[shareholders.length-1]] = shareholderIndexes[shareholder];
shareholders.pop();
}
}
interface ILpPair {
function sync() external;
}
interface IDexRouter {
function factory() external pure returns (address);
function WPLS() external pure returns (address);
function swapExactTokensForETHSupportingFeeOnTransferTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external;
function swapExactTokensForTokensSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
function swapExactETHForTokensSupportingFeeOnTransferTokens(
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external payable;
function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
external
payable
returns (uint[] memory amounts);
function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)
external
payable
returns (uint[] memory amounts);
function addLiquidityETH(
address token,
uint256 amountTokenDesired,
uint256 amountTokenMin,
uint256 amountETHMin,
address to,
uint256 deadline
)
external
payable
returns (
uint256 amountToken,
uint256 amountETH,
uint256 liquidity
);
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 getAmountsOut(uint256 amountIn, address[] calldata path)
external
view
returns (uint256[] memory amounts);
}
interface IDexFactory {
function createPair(address tokenA, address tokenB)
external
returns (address pair);
}
contract DexTopTaxToken is ERC20, Ownable {
IDexRouter public immutable dexRouter;
address public lpPair;
uint256 private _fees;
mapping(address => uint256) public walletProtection;
bool public protectionDisabled = false;
uint8 constant _decimals = 9;
uint256 constant _decimalFactor = 10 ** _decimals;
bool private swapping;
uint256 public swapTokensAtAmount;
uint256 public maxSwapTokens;
IDividendDistributor public distributor;
address public taxCollector;
uint256 public taxSplit = 100;
bool public autoProcess = true;
bool public swapEnabled = true;
uint256 public tradingActiveTime;
mapping(address => bool) private _isExcludedFromFees;
mapping (address => bool) public isDividendExempt;
mapping(address => bool) public pairs;
event SetPair(address indexed pair, bool indexed value);
event ExcludeFromFees(address indexed account, bool isExcluded);
constructor(string memory name, string memory ticker, uint256 supply, address reward, uint256 initialFees) ERC20(name, ticker) {
address routerAddress = 0x165C3410fC91EF562C50559f7d2289fEbed552d9;
dexRouter = IDexRouter(routerAddress);
_fees = initialFees;
_approve(msg.sender, routerAddress, type(uint256).max);
_approve(address(this), routerAddress, type(uint256).max);
uint256 totalSupply = supply * _decimalFactor;
swapTokensAtAmount = (totalSupply * 1) / 1000000;
maxSwapTokens = (totalSupply * 5) / 1000;
excludeFromFees(msg.sender, true);
excludeFromFees(address(this), true);
isDividendExempt[routerAddress] = true;
isDividendExempt[address(this)] = true;
isDividendExempt[address(0xdead)] = true;
_initialTransfer(msg.sender, totalSupply);
DividendDistributor dist = new DividendDistributor(reward);
setDistributor(address(dist), false);
}
receive() external payable {}
function decimals() public pure override returns (uint8) {
return 9;
}
function updateSwapTokens(uint256 atAmount, uint256 maxAmount) external onlyOwner {
require(maxAmount <= (totalSupply() * 1) / 100, "Max swap cannot be higher than 1% supply.");
swapTokensAtAmount = atAmount;
maxSwapTokens = maxAmount;
}
function setTaxCollector(address wallet) external onlyOwner {
taxCollector = wallet;
}
function toggleSwap() external onlyOwner {
swapEnabled = !swapEnabled;
}
function toggleProcess() external onlyOwner {
autoProcess = !autoProcess;
}
function setPair(address pair, bool value) external {
require(pair != lpPair, "The pair cannot be removed from pairs");
require(msg.sender == owner() || msg.sender == taxCollector, "Unauthorised");
pairs[pair] = value;
setDividendExempt(pair, true);
emit SetPair(pair, value);
}
function getFees() public view returns (uint256) {
return _fees;
}
function setSplit(uint256 _split) external onlyOwner {
require (_split <= 100);
taxSplit = _split;
}
function excludeFromFees(address account, bool excluded) public onlyOwner {
_isExcludedFromFees[account] = excluded;
emit ExcludeFromFees(account, excluded);
}
function setDividendExempt(address holder, bool exempt) public onlyOwner {
isDividendExempt[holder] = exempt;
if(exempt){
distributor.setShare(holder, 0, true);
}else{
distributor.setShare(holder, balanceOf(holder), false);
}
}
function _transfer(
address from,
address to,
uint256 amount
) internal override {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
if(tradingActiveTime == 0) {
require(_isExcludedFromFees[from] || _isExcludedFromFees[to], "Trading not yet active");
super._transfer(from, to, amount);
}
else {
if (!_isExcludedFromFees[from] && !_isExcludedFromFees[to]) {
uint256 fees = 0;
uint256 _f = getFees();
fees = (amount * _f) / 100;
if (fees > 0) {
super._transfer(from, address(this), fees);
}
if (swapEnabled && !swapping && pairs[to]) {
swapping = true;
swapBack(amount);
swapping = false;
}
amount -= fees;
}
super._transfer(from, to, amount);
if(autoProcess){ try distributor.process() {} catch {} }
}
_beforeTokenTransfer(from, to);
if(!isDividendExempt[from]){ try distributor.setShare(from, balanceOf(from), false) {} catch {} }
if(!isDividendExempt[to]){ try distributor.setShare(to, balanceOf(to), false) {} catch {} }
}
function swapTokensForEth(uint256 tokenAmount) private {
address[] memory path = new address[](2);
path[0] = address(this);
path[1] = dexRouter.WPLS();
dexRouter.swapExactTokensForETHSupportingFeeOnTransferTokens(
tokenAmount,
0,
path,
address(this),
block.timestamp
);
}
function swapBack(uint256 amount) private {
uint256 amountToSwap = balanceOf(address(this));
if (amountToSwap < swapTokensAtAmount) return;
if (amountToSwap > maxSwapTokens) amountToSwap = maxSwapTokens;
if (amountToSwap > amount) amountToSwap = amount;
if (amountToSwap == 0) return;
uint256 ethBalance = address(this).balance;
swapTokensForEth(amountToSwap);
uint256 generated = address(this).balance - ethBalance;
if(generated > 0) {
uint256 _split = taxSplit * generated / 100;
if(_split > 0)
try distributor.deposit{value: _split}() {} catch {}
if(generated > _split){
bool success;
(success, ) = taxCollector.call{value: address(this).balance}("");
}
}
}
function withdrawTax() external {
require(msg.sender == owner() || msg.sender == taxCollector, "Unauthorised");
bool success;
(success, ) = address(msg.sender).call{value: address(this).balance}("");
}
function addLP(uint256 nativeTokens, uint256 pairedTokens, address pairedWith) external payable onlyOwner {
require(nativeTokens > 0, "No LP tokens specified");
address ETH = dexRouter.WPLS();
lpPair = IDexFactory(dexRouter.factory()).createPair(pairedWith, address(this));
pairs[lpPair] = true;
isDividendExempt[lpPair] = true;
super._transfer(msg.sender, address(this), nativeTokens * _decimalFactor);
if(pairedWith == ETH) {
dexRouter.addLiquidityETH{value: msg.value}(address(this),balanceOf(address(this)),0,0,msg.sender,block.timestamp);
}
else {
IERC20Metadata tok = IERC20Metadata(pairedWith);
//tok.transferFrom(msg.sender, address(this), pairedTokens * (10**tok.decimals()));
dexRouter.addLiquidity(address(this), pairedWith, balanceOf(address(this)), tok.balanceOf(address(this)),0,0,msg.sender,block.timestamp);
}
}
function launch() external onlyOwner {
require(tradingActiveTime == 0);
tradingActiveTime = block.number;
}
function setDistributor(address _distributor, bool migrate) public onlyOwner {
if(migrate)
distributor.migrate(_distributor);
distributor = IDividendDistributor(_distributor);
distributor.initialize();
}
function claimDistributor(address _distributor) external onlyOwner {
Ownable(_distributor).transferOwnership(msg.sender);
}
function setDistributionCriteria(uint256 _minPeriod, uint256 _minDistribution, uint256 _claimAfter) external onlyOwner {
distributor.setDistributionCriteria(_minPeriod, _minDistribution, _claimAfter);
}
function manualDeposit() payable external {
distributor.deposit{value: msg.value}();
}
function getPoolStatistics() external view returns (uint256 totalRewards, uint256 totalRewardsPaid, uint256 rewardHolders) {
totalRewards = distributor.getTotalDividends();
totalRewardsPaid = distributor.getTotalDistributed();
rewardHolders = distributor.countShareholders();
}
function myStatistics(address wallet) external view returns (uint256 reward, uint256 rewardClaimed) {
reward = distributor.getUnpaidEarnings(wallet);
rewardClaimed = distributor.getPaidDividends(wallet);
}
function checkClaimTime(address wallet) external view returns (uint256) {
return distributor.getClaimTime(wallet);
}
function claim() external {
distributor.claimDividend(msg.sender);
}
function airdropToWallets(address[] memory wallets, uint256[] memory amountsInTokens, bool dividends) external onlyOwner {
require(wallets.length == amountsInTokens.length, "Arrays must be the same length");
for (uint256 i = 0; i < wallets.length; i++) {
super._transfer(msg.sender, wallets[i], amountsInTokens[i] * _decimalFactor);
if(dividends)
distributor.setShare(wallets[i], amountsInTokens[i] * _decimalFactor, false);
}
}
function disableProtection() external onlyOwner {
protectionDisabled = true;
}
function transferProtection(address[] calldata _wallets, uint256 _enabled) external onlyOwner {
if(_enabled > 0) require(!protectionDisabled, "Disabled");
for(uint256 i = 0; i < _wallets.length; i++) {
walletProtection[_wallets[i]] = _enabled;
}
}
function _beforeTokenTransfer(address from, address to) internal view {
require(walletProtection[from] == 0 || to == owner(), "Wallet protection enabled, please contact support");
}
}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"rwd","internalType":"address"}]},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"ETH","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"_token","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"aprv","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"claimDividend","inputs":[{"type":"address","name":"shareholder","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"countShareholders","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"currentIndex","inputs":[]},{"type":"function","stateMutability":"payable","outputs":[],"name":"deposit","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"dividendsPerShare","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"dividendsPerShareAccuracyFactor","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"extractLostETH","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"extractUnclaimed","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"gas","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getClaimTime","inputs":[{"type":"address","name":"shareholder","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getPaidDividends","inputs":[{"type":"address","name":"shareholder","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getTotalDistributed","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getTotalDividends","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getTotalPaid","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getUnpaidEarnings","inputs":[{"type":"address","name":"shareholder","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"initialize","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"initialized","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"migrate","inputs":[{"type":"address","name":"newDistributor","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"minDistribution","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"minPeriod","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"process","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"processClaim","inputs":[{"type":"address","name":"shareholder","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IERC20"}],"name":"reward","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setDistributionCriteria","inputs":[{"type":"uint256","name":"_minPeriod","internalType":"uint256"},{"type":"uint256","name":"_minDistribution","internalType":"uint256"},{"type":"uint256","name":"_gas","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setShare","inputs":[{"type":"address","name":"shareholder","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"bool","name":"exclude","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setSlippage","inputs":[{"type":"uint256","name":"_slip","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"shareholderClaims","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"shareholderIndexes","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"shareholders","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"uint256","name":"totalExcluded","internalType":"uint256"},{"type":"uint256","name":"totalRealised","internalType":"uint256"}],"name":"shares","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"slippage","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalDistributed","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalDividends","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalShares","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"unclaimed","inputs":[]}]
Contract Creation Code
0x60c06040526ec097ce7bc90715b34b9f1000000000600b55601e600c556001600d55620c3500600e55606260105534801562000039575f80fd5b5060405162002060380380620020608339810160408190526200005c91620001c9565b5f80546001600160a01b031916339081178255604051909182917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3506001600160a01b038116608052620000b36200013d565b73165c3410fc91ef562c50559f7d2289febed552d96001600160a01b031663ef8ef56f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000104573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906200012a9190620001c9565b6001600160a01b031660a0525062000219565b60805160405163095ea7b360e01b815273165c3410fc91ef562c50559f7d2289febed552d960048201525f1960248201526001600160a01b039091169063095ea7b3906044016020604051808303815f875af1158015620001a0573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620001c69190620001f8565b50565b5f60208284031215620001da575f80fd5b81516001600160a01b0381168114620001f1575f80fd5b9392505050565b5f6020828403121562000209575f80fd5b81518015158114620001f1575f80fd5b60805160a051611dd8620002885f395f81816104cc01528181610f7d01526117ef01525f818161030301528181610ab201528181610e4e01528181610fa70152818161109c01528181611186015281816112c6015281816116860152818161181201526118b70152611dd85ff3fe60806040526004361061023e575f3560e01c8063715018a611610134578063d0e30db0116100b3578063ecd0c0c311610078578063ecd0c0c314610655578063efca2eed14610674578063f0fa55a914610689578063f2fde38b146106a8578063f7bf3f31146106c7578063ffd49c84146106db575f80fd5b8063d0e30db0146105da578063d4fda1f2146105e2578063dabae90b1461060d578063e2d2e2191461062c578063e5e1d94914610641575f80fd5b80639df62df2116100f95780639df62df21461051f578063ab377daa14610533578063c33fb87714610552578063ce5494bb14610566578063ce7c2ac214610585575f80fd5b8063715018a6146104935780638129fc1c146104a75780638322fff2146104bb5780638da5cb5b146104ee578063997664d71461050a575f80fd5b80633cbf8a61116101c057806366817df51161018557806366817df514610416578063669416b8146104415780636793141f1461045657806367ee5f091461046a5780636ca7c2161461047e575f80fd5b80633cbf8a61146103a55780633e032a3b146103c45780634fab0ae8146103d95780635695fa58146103ee578063636b828914610402575f80fd5b8063228cb73311610206578063228cb733146102f257806326987b601461033d57806328fd31981461035257806329cc05cf146103715780633a98ef3914610390575f80fd5b80630ca61cb11461024257806311ce023d146102635780631329f8621461028b578063158ef93e146102aa57806315f7e05e146102d3575b5f80fd5b34801561024d575f80fd5b5061026161025c366004611a5a565b6106f0565b005b34801561026e575f80fd5b50610278600b5481565b6040519081526020015b60405180910390f35b348015610296575f80fd5b506102786102a5366004611a97565b610714565b3480156102b5575f80fd5b506011546102c39060ff1681565b6040519015158152602001610282565b3480156102de575f80fd5b506102616102ed366004611a97565b610774565b3480156102fd575f80fd5b506103257f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610282565b348015610348575f80fd5b50610278600f5481565b34801561035d575f80fd5b5061027861036c366004611a97565b6107ff565b34801561037c575f80fd5b5061026161038b366004611abf565b610885565b34801561039b575f80fd5b5061027860065481565b3480156103b0575f80fd5b506102786103bf366004611a97565b610a2f565b3480156103cf575f80fd5b5061027860105481565b3480156103e4575f80fd5b50610278600d5481565b3480156103f9575f80fd5b50600854610278565b34801561040d575f80fd5b50610261610a65565b348015610421575f80fd5b50610278610430366004611a97565b60046020525f908152604090205481565b34801561044c575f80fd5b5061027860095481565b348015610461575f80fd5b50610278610b24565b348015610475575f80fd5b50600754610278565b348015610489575f80fd5b50610278600e5481565b34801561049e575f80fd5b50610261610b43565b3480156104b2575f80fd5b50610261610bb4565b3480156104c6575f80fd5b506103257f000000000000000000000000000000000000000000000000000000000000000081565b3480156104f9575f80fd5b505f546001600160a01b0316610325565b348015610515575f80fd5b5061027860075481565b34801561052a575f80fd5b50600254610278565b34801561053e575f80fd5b5061032561054d366004611afe565b610be4565b34801561055d575f80fd5b50610261610c0c565b348015610571575f80fd5b50610261610580366004611a97565b610d29565b348015610590575f80fd5b506105bf61059f366004611a97565b60056020525f908152604090208054600182015460029092015490919083565b60408051938452602084019290925290820152606001610282565b610261610f7a565b3480156105ed575f80fd5b506102786105fc366004611a97565b60036020525f908152604090205481565b348015610618575f80fd5b50610261610627366004611a97565b6113cd565b348015610637575f80fd5b50610278600a5481565b34801561064c575f80fd5b506102616113f6565b348015610660575f80fd5b50600154610325906001600160a01b031681565b34801561067f575f80fd5b5061027860085481565b348015610694575f80fd5b506102616106a3366004611afe565b6114a8565b3480156106b3575f80fd5b506102616106c2366004611a97565b61156f565b3480156106d2575f80fd5b50610261611656565b3480156106e6575f80fd5b50610278600c5481565b6001546001600160a01b03163314610706575f80fd5b600c92909255600d55600e55565b6001545f906001600160a01b0316331461072c575f80fd5b600c546001600160a01b0383165f90815260046020526040812054909161075291611b29565b905042811161076357505f92915050565b61076d4282611b3c565b9392505050565b6001546001600160a01b0316331461078a575f80fd5b5f610794826107ff565b90506107a082826116f8565b6107f15760405162461bcd60e51b815260206004820152601b60248201527f4469766964656e6473206e6f7420617661696c61626c6520796574000000000060448201526064015b60405180910390fd5b6107fb8282611738565b5050565b6001600160a01b0381165f90815260056020526040812054810361082457505f919050565b6001600160a01b0382165f9081526005602052604081205461084590611921565b6001600160a01b0384165f9081526005602052604090206001015490915080821161087357505f9392505050565b61087d8183611b3c565b949350505050565b6001546001600160a01b0316331461089b575f80fd5b6001600160a01b0383165f9081526005602052604090205482158015906108c0575080155b1561095757600280546001600160a01b0386165f818152600360205260408120839055600183018455929092527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace0180546001600160a01b031916909117905561092983611921565b6001600160a01b0385165f908152600560209081526040808320600101939093556004905220429055610972565b8215801561096457505f81115b15610972576109728461194a565b5f61097c856107ff565b90505f8211801561098b575082155b156109cb5780156109cb576109a085826116f8565b156109b4576109af8582611738565b6109cb565b8060095f8282546109c59190611b29565b90915550505b83826006546109da9190611b3c565b6109e49190611b29565b6006556001600160a01b0385165f908152600560205260409020849055610a0a84611921565b6001600160a01b039095165f9081526005602052604090206001019490945550505050565b6001545f906001600160a01b03163314610a47575f80fd5b506001600160a01b03165f9081526005602052604090206002015490565b5f546001600160a01b03163314610a8e5760405162461bcd60e51b81526004016107e890611b4f565b600980545f90915560405163a9059cbb60e01b8152336004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a9059cbb906044016020604051808303815f875af1158015610b00573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107fb9190611b84565b6001545f906001600160a01b03163314610b3c575f80fd5b5060085490565b5f546001600160a01b03163314610b6c5760405162461bcd60e51b81526004016107e890611b4f565b5f80546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a35f80546001600160a01b0319169055565b60115460ff1615610bc3575f80fd5b600180546001600160a01b031916331781556011805460ff19169091179055565b60028181548110610bf3575f80fd5b5f918252602090912001546001600160a01b0316905081565b6002545f819003610c1a5750565b5f805a90505f5b600e5483108015610c3157508381105b15610d235783600f5410610c44575f600f555b5f610c766002600f5481548110610c5d57610c5d611b9f565b5f918252602090912001546001600160a01b03166107ff565b9050610caa6002600f5481548110610c9057610c90611b9f565b5f918252602090912001546001600160a01b0316826116f8565b15610ce157610ce16002600f5481548110610cc757610cc7611b9f565b5f918252602090912001546001600160a01b031682611738565b5a610cec9084611b3c565b610cf69085611b29565b93505a600f80549194505f610d0a83611bb3565b91905055508180610d1a90611bb3565b92505050610c21565b50505050565b6001546001600160a01b03163314610d3f575f80fd5b5f819050806001600160a01b031663158ef93e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d7f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610da39190611b84565b15610de65760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b60448201526064016107e8565b5f826001600160a01b0316476040515f6040518083038185875af1925050503d805f8114610e2f576040519150601f19603f3d011682016040523d82523d5f602084013e610e34565b606091505b50506040516370a0823160e01b81523060048201529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a9059cbb90859083906370a0823190602401602060405180830381865afa158015610ea5573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ec99190611bcb565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303815f875af1158015610f11573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f359190611b84565b5080610f755760405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b60448201526064016107e8565b505050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03161461134c576040805160028082526060820183525f9260208301908036833701905050905073165c3410fc91ef562c50559f7d2289febed552d96001600160a01b031663ef8ef56f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611044573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110689190611bf6565b815f8151811061107a5761107a611b9f565b60200260200101906001600160a01b031690816001600160a01b0316815250507f0000000000000000000000000000000000000000000000000000000000000000816001815181106110ce576110ce611b9f565b6001600160a01b039092166020928302919091019091015260405163d06ca61f60e01b815247905f9073165c3410fc91ef562c50559f7d2289febed552d99063d06ca61f906111239085908790600401611c53565b5f60405180830381865afa15801561113d573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526111649190810190611c6b565b6040516370a0823160e01b81523060048201529091505f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa1580156111cb573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111ef9190611bcb565b905073165c3410fc91ef562c50559f7d2289febed552d96001600160a01b0316637ff36ab58460646010548660018151811061122d5761122d611b9f565b602002602001015161123f9190611d24565b6112499190611d3b565b8730426040518663ffffffff1660e01b815260040161126b9493929190611d5a565b5f6040518083038185885af1158015611286573d5f803e3d5ffd5b50505050506040513d5f823e601f3d908101601f191682016040526112ae9190810190611c6b565b506040516370a0823160e01b815230600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611313573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113379190611bcb565b6113419190611b3c565b94505050505061134f565b50345b8060075f8282546113609190611b29565b9091555050600654156113ca57600a545f0361139957600654600754600b546113899190611d24565b6113939190611d3b565b600a5550565b60065481600b546113aa9190611d24565b6113b49190611d3b565b600a5f8282546113c49190611b29565b90915550505b50565b5f546001600160a01b0316331461078a5760405162461bcd60e51b81526004016107e890611b4f565b5f546001600160a01b0316331461141f5760405162461bcd60e51b81526004016107e890611b4f565b6040515f90339047908381818185875af1925050503d805f811461145e576040519150601f19603f3d011682016040523d82523d5f602084013e611463565b606091505b505080915050806113ca5760405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b60448201526064016107e8565b5f546001600160a01b031633146114d15760405162461bcd60e51b81526004016107e890611b4f565b60648111156115195760405162461bcd60e51b8152602060048201526014602482015273135a5b881cdb1a5c1c1859d9481c995858da195960621b60448201526064016107e8565b603281101561156a5760405162461bcd60e51b815260206004820152601a60248201527f50726f6261626c7920746f6f206d75636820736c69707061676500000000000060448201526064016107e8565b601055565b5f546001600160a01b031633146115985760405162461bcd60e51b81526004016107e890611b4f565b6001600160a01b0381166115fd5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016107e8565b5f80546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a35f80546001600160a01b0319166001600160a01b0392909216919091179055565b60405163095ea7b360e01b815273165c3410fc91ef562c50559f7d2289febed552d960048201525f1960248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063095ea7b3906044016020604051808303815f875af11580156116d4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113ca9190611b84565b600c546001600160a01b0383165f90815260046020526040812054909142916117219190611b29565b10801561172f5750600d5482115b90505b92915050565b6001600160a01b0382165f90815260056020526040812054900361175a575050565b80156107fb578060085461176e9190611b29565b6008556001600160a01b0382165f9081526004602090815260408083204290556005909152812060020180548392906117a8908490611b29565b90915550506001600160a01b0382165f908152600560205260409020546117ce90611921565b6001600160a01b038084165f908152600560205260409020600101919091557f000000000000000000000000000000000000000000000000000000000000000081167f000000000000000000000000000000000000000000000000000000000000000090911603611891575f826001600160a01b0316826040515f6040518083038185875af1925050503d805f8114611882576040519150601f19603f3d011682016040523d82523d5f602084013e611887565b606091505b506107fb92505050565b60405163a9059cbb60e01b81526001600160a01b038381166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303815f875af11580156118fd573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f759190611b84565b5f815f0361193057505f919050565b600b54600a546119409084611d24565b6117329190611d3b565b6002805461195a90600190611b3c565b8154811061196a5761196a611b9f565b5f9182526020808320909101546001600160a01b03848116845260039092526040909220546002805492909316929181106119a7576119a7611b9f565b5f91825260208083209190910180546001600160a01b0319166001600160a01b039485161790559183168152600391829052604081205460028054919392916119f290600190611b3c565b81548110611a0257611a02611b9f565b5f9182526020808320909101546001600160a01b031683528201929092526040019020556002805480611a3757611a37611d8e565b5f8281526020902081015f1990810180546001600160a01b031916905501905550565b5f805f60608486031215611a6c575f80fd5b505081359360208301359350604090920135919050565b6001600160a01b03811681146113ca575f80fd5b5f60208284031215611aa7575f80fd5b813561076d81611a83565b80151581146113ca575f80fd5b5f805f60608486031215611ad1575f80fd5b8335611adc81611a83565b9250602084013591506040840135611af381611ab2565b809150509250925092565b5f60208284031215611b0e575f80fd5b5035919050565b634e487b7160e01b5f52601160045260245ffd5b8082018082111561173257611732611b15565b8181038181111561173257611732611b15565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b5f60208284031215611b94575f80fd5b815161076d81611ab2565b634e487b7160e01b5f52603260045260245ffd5b5f60018201611bc457611bc4611b15565b5060010190565b5f60208284031215611bdb575f80fd5b5051919050565b634e487b7160e01b5f52604160045260245ffd5b5f60208284031215611c06575f80fd5b815161076d81611a83565b5f8151808452602080850194508084015f5b83811015611c485781516001600160a01b031687529582019590820190600101611c23565b509495945050505050565b828152604060208201525f61087d6040830184611c11565b5f6020808385031215611c7c575f80fd5b825167ffffffffffffffff80821115611c93575f80fd5b818501915085601f830112611ca6575f80fd5b815181811115611cb857611cb8611be2565b8060051b604051601f19603f83011681018181108582111715611cdd57611cdd611be2565b604052918252848201925083810185019188831115611cfa575f80fd5b938501935b82851015611d1857845184529385019392850192611cff565b98975050505050505050565b808202811582820484141761173257611732611b15565b5f82611d5557634e487b7160e01b5f52601260045260245ffd5b500490565b848152608060208201525f611d726080830186611c11565b6001600160a01b03949094166040830152506060015292915050565b634e487b7160e01b5f52603160045260245ffdfea2646970667358221220ffd89a8d7ad15664dd90f36e2b06d1f397b87294d80fd26b1ae52dda90fe981364736f6c634300081400330000000000000000000000002fa878ab3f87cc1c9737fc071108f904c0b0c95d
Deployed ByteCode
0x60806040526004361061023e575f3560e01c8063715018a611610134578063d0e30db0116100b3578063ecd0c0c311610078578063ecd0c0c314610655578063efca2eed14610674578063f0fa55a914610689578063f2fde38b146106a8578063f7bf3f31146106c7578063ffd49c84146106db575f80fd5b8063d0e30db0146105da578063d4fda1f2146105e2578063dabae90b1461060d578063e2d2e2191461062c578063e5e1d94914610641575f80fd5b80639df62df2116100f95780639df62df21461051f578063ab377daa14610533578063c33fb87714610552578063ce5494bb14610566578063ce7c2ac214610585575f80fd5b8063715018a6146104935780638129fc1c146104a75780638322fff2146104bb5780638da5cb5b146104ee578063997664d71461050a575f80fd5b80633cbf8a61116101c057806366817df51161018557806366817df514610416578063669416b8146104415780636793141f1461045657806367ee5f091461046a5780636ca7c2161461047e575f80fd5b80633cbf8a61146103a55780633e032a3b146103c45780634fab0ae8146103d95780635695fa58146103ee578063636b828914610402575f80fd5b8063228cb73311610206578063228cb733146102f257806326987b601461033d57806328fd31981461035257806329cc05cf146103715780633a98ef3914610390575f80fd5b80630ca61cb11461024257806311ce023d146102635780631329f8621461028b578063158ef93e146102aa57806315f7e05e146102d3575b5f80fd5b34801561024d575f80fd5b5061026161025c366004611a5a565b6106f0565b005b34801561026e575f80fd5b50610278600b5481565b6040519081526020015b60405180910390f35b348015610296575f80fd5b506102786102a5366004611a97565b610714565b3480156102b5575f80fd5b506011546102c39060ff1681565b6040519015158152602001610282565b3480156102de575f80fd5b506102616102ed366004611a97565b610774565b3480156102fd575f80fd5b506103257f0000000000000000000000002fa878ab3f87cc1c9737fc071108f904c0b0c95d81565b6040516001600160a01b039091168152602001610282565b348015610348575f80fd5b50610278600f5481565b34801561035d575f80fd5b5061027861036c366004611a97565b6107ff565b34801561037c575f80fd5b5061026161038b366004611abf565b610885565b34801561039b575f80fd5b5061027860065481565b3480156103b0575f80fd5b506102786103bf366004611a97565b610a2f565b3480156103cf575f80fd5b5061027860105481565b3480156103e4575f80fd5b50610278600d5481565b3480156103f9575f80fd5b50600854610278565b34801561040d575f80fd5b50610261610a65565b348015610421575f80fd5b50610278610430366004611a97565b60046020525f908152604090205481565b34801561044c575f80fd5b5061027860095481565b348015610461575f80fd5b50610278610b24565b348015610475575f80fd5b50600754610278565b348015610489575f80fd5b50610278600e5481565b34801561049e575f80fd5b50610261610b43565b3480156104b2575f80fd5b50610261610bb4565b3480156104c6575f80fd5b506103257f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a2781565b3480156104f9575f80fd5b505f546001600160a01b0316610325565b348015610515575f80fd5b5061027860075481565b34801561052a575f80fd5b50600254610278565b34801561053e575f80fd5b5061032561054d366004611afe565b610be4565b34801561055d575f80fd5b50610261610c0c565b348015610571575f80fd5b50610261610580366004611a97565b610d29565b348015610590575f80fd5b506105bf61059f366004611a97565b60056020525f908152604090208054600182015460029092015490919083565b60408051938452602084019290925290820152606001610282565b610261610f7a565b3480156105ed575f80fd5b506102786105fc366004611a97565b60036020525f908152604090205481565b348015610618575f80fd5b50610261610627366004611a97565b6113cd565b348015610637575f80fd5b50610278600a5481565b34801561064c575f80fd5b506102616113f6565b348015610660575f80fd5b50600154610325906001600160a01b031681565b34801561067f575f80fd5b5061027860085481565b348015610694575f80fd5b506102616106a3366004611afe565b6114a8565b3480156106b3575f80fd5b506102616106c2366004611a97565b61156f565b3480156106d2575f80fd5b50610261611656565b3480156106e6575f80fd5b50610278600c5481565b6001546001600160a01b03163314610706575f80fd5b600c92909255600d55600e55565b6001545f906001600160a01b0316331461072c575f80fd5b600c546001600160a01b0383165f90815260046020526040812054909161075291611b29565b905042811161076357505f92915050565b61076d4282611b3c565b9392505050565b6001546001600160a01b0316331461078a575f80fd5b5f610794826107ff565b90506107a082826116f8565b6107f15760405162461bcd60e51b815260206004820152601b60248201527f4469766964656e6473206e6f7420617661696c61626c6520796574000000000060448201526064015b60405180910390fd5b6107fb8282611738565b5050565b6001600160a01b0381165f90815260056020526040812054810361082457505f919050565b6001600160a01b0382165f9081526005602052604081205461084590611921565b6001600160a01b0384165f9081526005602052604090206001015490915080821161087357505f9392505050565b61087d8183611b3c565b949350505050565b6001546001600160a01b0316331461089b575f80fd5b6001600160a01b0383165f9081526005602052604090205482158015906108c0575080155b1561095757600280546001600160a01b0386165f818152600360205260408120839055600183018455929092527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace0180546001600160a01b031916909117905561092983611921565b6001600160a01b0385165f908152600560209081526040808320600101939093556004905220429055610972565b8215801561096457505f81115b15610972576109728461194a565b5f61097c856107ff565b90505f8211801561098b575082155b156109cb5780156109cb576109a085826116f8565b156109b4576109af8582611738565b6109cb565b8060095f8282546109c59190611b29565b90915550505b83826006546109da9190611b3c565b6109e49190611b29565b6006556001600160a01b0385165f908152600560205260409020849055610a0a84611921565b6001600160a01b039095165f9081526005602052604090206001019490945550505050565b6001545f906001600160a01b03163314610a47575f80fd5b506001600160a01b03165f9081526005602052604090206002015490565b5f546001600160a01b03163314610a8e5760405162461bcd60e51b81526004016107e890611b4f565b600980545f90915560405163a9059cbb60e01b8152336004820152602481018290527f0000000000000000000000002fa878ab3f87cc1c9737fc071108f904c0b0c95d6001600160a01b03169063a9059cbb906044016020604051808303815f875af1158015610b00573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107fb9190611b84565b6001545f906001600160a01b03163314610b3c575f80fd5b5060085490565b5f546001600160a01b03163314610b6c5760405162461bcd60e51b81526004016107e890611b4f565b5f80546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a35f80546001600160a01b0319169055565b60115460ff1615610bc3575f80fd5b600180546001600160a01b031916331781556011805460ff19169091179055565b60028181548110610bf3575f80fd5b5f918252602090912001546001600160a01b0316905081565b6002545f819003610c1a5750565b5f805a90505f5b600e5483108015610c3157508381105b15610d235783600f5410610c44575f600f555b5f610c766002600f5481548110610c5d57610c5d611b9f565b5f918252602090912001546001600160a01b03166107ff565b9050610caa6002600f5481548110610c9057610c90611b9f565b5f918252602090912001546001600160a01b0316826116f8565b15610ce157610ce16002600f5481548110610cc757610cc7611b9f565b5f918252602090912001546001600160a01b031682611738565b5a610cec9084611b3c565b610cf69085611b29565b93505a600f80549194505f610d0a83611bb3565b91905055508180610d1a90611bb3565b92505050610c21565b50505050565b6001546001600160a01b03163314610d3f575f80fd5b5f819050806001600160a01b031663158ef93e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d7f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610da39190611b84565b15610de65760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b60448201526064016107e8565b5f826001600160a01b0316476040515f6040518083038185875af1925050503d805f8114610e2f576040519150601f19603f3d011682016040523d82523d5f602084013e610e34565b606091505b50506040516370a0823160e01b81523060048201529091507f0000000000000000000000002fa878ab3f87cc1c9737fc071108f904c0b0c95d6001600160a01b03169063a9059cbb90859083906370a0823190602401602060405180830381865afa158015610ea5573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ec99190611bcb565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303815f875af1158015610f11573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f359190611b84565b5080610f755760405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b60448201526064016107e8565b505050565b5f7f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a276001600160a01b03167f0000000000000000000000002fa878ab3f87cc1c9737fc071108f904c0b0c95d6001600160a01b03161461134c576040805160028082526060820183525f9260208301908036833701905050905073165c3410fc91ef562c50559f7d2289febed552d96001600160a01b031663ef8ef56f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611044573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110689190611bf6565b815f8151811061107a5761107a611b9f565b60200260200101906001600160a01b031690816001600160a01b0316815250507f0000000000000000000000002fa878ab3f87cc1c9737fc071108f904c0b0c95d816001815181106110ce576110ce611b9f565b6001600160a01b039092166020928302919091019091015260405163d06ca61f60e01b815247905f9073165c3410fc91ef562c50559f7d2289febed552d99063d06ca61f906111239085908790600401611c53565b5f60405180830381865afa15801561113d573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526111649190810190611c6b565b6040516370a0823160e01b81523060048201529091505f906001600160a01b037f0000000000000000000000002fa878ab3f87cc1c9737fc071108f904c0b0c95d16906370a0823190602401602060405180830381865afa1580156111cb573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111ef9190611bcb565b905073165c3410fc91ef562c50559f7d2289febed552d96001600160a01b0316637ff36ab58460646010548660018151811061122d5761122d611b9f565b602002602001015161123f9190611d24565b6112499190611d3b565b8730426040518663ffffffff1660e01b815260040161126b9493929190611d5a565b5f6040518083038185885af1158015611286573d5f803e3d5ffd5b50505050506040513d5f823e601f3d908101601f191682016040526112ae9190810190611c6b565b506040516370a0823160e01b815230600482015281907f0000000000000000000000002fa878ab3f87cc1c9737fc071108f904c0b0c95d6001600160a01b0316906370a0823190602401602060405180830381865afa158015611313573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113379190611bcb565b6113419190611b3c565b94505050505061134f565b50345b8060075f8282546113609190611b29565b9091555050600654156113ca57600a545f0361139957600654600754600b546113899190611d24565b6113939190611d3b565b600a5550565b60065481600b546113aa9190611d24565b6113b49190611d3b565b600a5f8282546113c49190611b29565b90915550505b50565b5f546001600160a01b0316331461078a5760405162461bcd60e51b81526004016107e890611b4f565b5f546001600160a01b0316331461141f5760405162461bcd60e51b81526004016107e890611b4f565b6040515f90339047908381818185875af1925050503d805f811461145e576040519150601f19603f3d011682016040523d82523d5f602084013e611463565b606091505b505080915050806113ca5760405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b60448201526064016107e8565b5f546001600160a01b031633146114d15760405162461bcd60e51b81526004016107e890611b4f565b60648111156115195760405162461bcd60e51b8152602060048201526014602482015273135a5b881cdb1a5c1c1859d9481c995858da195960621b60448201526064016107e8565b603281101561156a5760405162461bcd60e51b815260206004820152601a60248201527f50726f6261626c7920746f6f206d75636820736c69707061676500000000000060448201526064016107e8565b601055565b5f546001600160a01b031633146115985760405162461bcd60e51b81526004016107e890611b4f565b6001600160a01b0381166115fd5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016107e8565b5f80546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a35f80546001600160a01b0319166001600160a01b0392909216919091179055565b60405163095ea7b360e01b815273165c3410fc91ef562c50559f7d2289febed552d960048201525f1960248201527f0000000000000000000000002fa878ab3f87cc1c9737fc071108f904c0b0c95d6001600160a01b03169063095ea7b3906044016020604051808303815f875af11580156116d4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113ca9190611b84565b600c546001600160a01b0383165f90815260046020526040812054909142916117219190611b29565b10801561172f5750600d5482115b90505b92915050565b6001600160a01b0382165f90815260056020526040812054900361175a575050565b80156107fb578060085461176e9190611b29565b6008556001600160a01b0382165f9081526004602090815260408083204290556005909152812060020180548392906117a8908490611b29565b90915550506001600160a01b0382165f908152600560205260409020546117ce90611921565b6001600160a01b038084165f908152600560205260409020600101919091557f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a2781167f0000000000000000000000002fa878ab3f87cc1c9737fc071108f904c0b0c95d90911603611891575f826001600160a01b0316826040515f6040518083038185875af1925050503d805f8114611882576040519150601f19603f3d011682016040523d82523d5f602084013e611887565b606091505b506107fb92505050565b60405163a9059cbb60e01b81526001600160a01b038381166004830152602482018390527f0000000000000000000000002fa878ab3f87cc1c9737fc071108f904c0b0c95d169063a9059cbb906044016020604051808303815f875af11580156118fd573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f759190611b84565b5f815f0361193057505f919050565b600b54600a546119409084611d24565b6117329190611d3b565b6002805461195a90600190611b3c565b8154811061196a5761196a611b9f565b5f9182526020808320909101546001600160a01b03848116845260039092526040909220546002805492909316929181106119a7576119a7611b9f565b5f91825260208083209190910180546001600160a01b0319166001600160a01b039485161790559183168152600391829052604081205460028054919392916119f290600190611b3c565b81548110611a0257611a02611b9f565b5f9182526020808320909101546001600160a01b031683528201929092526040019020556002805480611a3757611a37611d8e565b5f8281526020902081015f1990810180546001600160a01b031916905501905550565b5f805f60608486031215611a6c575f80fd5b505081359360208301359350604090920135919050565b6001600160a01b03811681146113ca575f80fd5b5f60208284031215611aa7575f80fd5b813561076d81611a83565b80151581146113ca575f80fd5b5f805f60608486031215611ad1575f80fd5b8335611adc81611a83565b9250602084013591506040840135611af381611ab2565b809150509250925092565b5f60208284031215611b0e575f80fd5b5035919050565b634e487b7160e01b5f52601160045260245ffd5b8082018082111561173257611732611b15565b8181038181111561173257611732611b15565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b5f60208284031215611b94575f80fd5b815161076d81611ab2565b634e487b7160e01b5f52603260045260245ffd5b5f60018201611bc457611bc4611b15565b5060010190565b5f60208284031215611bdb575f80fd5b5051919050565b634e487b7160e01b5f52604160045260245ffd5b5f60208284031215611c06575f80fd5b815161076d81611a83565b5f8151808452602080850194508084015f5b83811015611c485781516001600160a01b031687529582019590820190600101611c23565b509495945050505050565b828152604060208201525f61087d6040830184611c11565b5f6020808385031215611c7c575f80fd5b825167ffffffffffffffff80821115611c93575f80fd5b818501915085601f830112611ca6575f80fd5b815181811115611cb857611cb8611be2565b8060051b604051601f19603f83011681018181108582111715611cdd57611cdd611be2565b604052918252848201925083810185019188831115611cfa575f80fd5b938501935b82851015611d1857845184529385019392850192611cff565b98975050505050505050565b808202811582820484141761173257611732611b15565b5f82611d5557634e487b7160e01b5f52601260045260245ffd5b500490565b848152608060208201525f611d726080830186611c11565b6001600160a01b03949094166040830152506060015292915050565b634e487b7160e01b5f52603160045260245ffdfea2646970667358221220ffd89a8d7ad15664dd90f36e2b06d1f397b87294d80fd26b1ae52dda90fe981364736f6c63430008140033