文件 1 的 1:PIVOT.sol
pragma solidity 0.8.19;
interface IUniswapV2Router01 {
function factory() external pure returns (address);
function WETH() external pure returns (address);
function addLiquidity(
address tokenA,
address tokenB,
uint amountADesired,
uint amountBDesired,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
) external returns (uint amountA, uint amountB, uint liquidity);
function addLiquidityETH(
address token,
uint amountTokenDesired,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
)
external
payable
returns (uint amountToken, uint amountETH, uint liquidity);
function removeLiquidity(
address tokenA,
address tokenB,
uint liquidity,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
) external returns (uint amountA, uint amountB);
function removeLiquidityETH(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external returns (uint amountToken, uint amountETH);
function removeLiquidityWithPermit(
address tokenA,
address tokenB,
uint liquidity,
uint amountAMin,
uint amountBMin,
address to,
uint deadline,
bool approveMax,
uint8 v,
bytes32 r,
bytes32 s
) external returns (uint amountA, uint amountB);
function removeLiquidityETHWithPermit(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline,
bool approveMax,
uint8 v,
bytes32 r,
bytes32 s
) external returns (uint amountToken, uint amountETH);
function swapExactTokensForTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external returns (uint[] memory amounts);
function swapTokensForExactTokens(
uint amountOut,
uint amountInMax,
address[] calldata path,
address to,
uint deadline
) external returns (uint[] memory amounts);
function swapExactETHForTokens(
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external payable returns (uint[] memory amounts);
function swapTokensForExactETH(
uint amountOut,
uint amountInMax,
address[] calldata path,
address to,
uint deadline
) external returns (uint[] memory amounts);
function swapExactTokensForETH(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external returns (uint[] memory amounts);
function swapETHForExactTokens(
uint amountOut,
address[] calldata path,
address to,
uint deadline
) external payable returns (uint[] memory amounts);
function quote(
uint amountA,
uint reserveA,
uint reserveB
) external pure returns (uint amountB);
function getAmountOut(
uint amountIn,
uint reserveIn,
uint reserveOut
) external pure returns (uint amountOut);
function getAmountIn(
uint amountOut,
uint reserveIn,
uint reserveOut
) external pure returns (uint amountIn);
function getAmountsOut(
uint amountIn,
address[] calldata path
) external view returns (uint[] memory amounts);
function getAmountsIn(
uint amountOut,
address[] calldata path
) external view returns (uint[] memory amounts);
}
interface IUniswapV2Router02 is IUniswapV2Router01 {
function removeLiquidityETHSupportingFeeOnTransferTokens(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external returns (uint amountETH);
function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline,
bool approveMax,
uint8 v,
bytes32 r,
bytes32 s
) external returns (uint amountETH);
function swapExactTokensForTokensSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
function swapExactETHForTokensSupportingFeeOnTransferTokens(
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external payable;
function swapExactTokensForETHSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
}
interface IUniswapV2Factory {
event PairCreated(
address indexed token0,
address indexed token1,
address pair,
uint
);
function feeTo() external view returns (address);
function feeToSetter() external view returns (address);
function getPair(
address tokenA,
address tokenB
) external view returns (address pair);
function allPairs(uint) external view returns (address pair);
function allPairsLength() external view returns (uint);
function createPair(
address tokenA,
address tokenB
) external returns (address pair);
function setFeeTo(address) external;
function setFeeToSetter(address) external;
}
library Address {
function isContract(address account) internal view returns (bool) {
return account.code.length > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(
address(this).balance >= amount,
"Address: insufficient balance"
);
(bool success, ) = recipient.call{value: amount}("");
require(
success,
"Address: unable to send value, recipient may have reverted"
);
}
function functionCall(
address target,
bytes memory data
) internal returns (bytes memory) {
return
functionCallWithValue(
target,
data,
0,
"Address: low-level call failed"
);
}
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return
functionCallWithValue(
target,
data,
value,
"Address: low-level call with value failed"
);
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(
address(this).balance >= value,
"Address: insufficient balance for call"
);
(bool success, bytes memory returndata) = target.call{value: value}(
data
);
return
verifyCallResultFromTarget(
target,
success,
returndata,
errorMessage
);
}
function functionStaticCall(
address target,
bytes memory data
) internal view returns (bytes memory) {
return
functionStaticCall(
target,
data,
"Address: low-level static call failed"
);
}
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return
verifyCallResultFromTarget(
target,
success,
returndata,
errorMessage
);
}
function functionDelegateCall(
address target,
bytes memory data
) internal returns (bytes memory) {
return
functionDelegateCall(
target,
data,
"Address: low-level delegate call failed"
);
}
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return
verifyCallResultFromTarget(
target,
success,
returndata,
errorMessage
);
}
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(
bytes memory returndata,
string memory errorMessage
) private pure {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
interface IERC20Permit {
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
function nonces(address owner) external view returns (uint256);
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function allowance(
address owner,
address spender
) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}
library SafeERC20 {
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(
token,
abi.encodeWithSelector(token.transfer.selector, to, value)
);
}
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(
token,
abi.encodeWithSelector(token.transferFrom.selector, from, to, value)
);
}
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(
token,
abi.encodeWithSelector(token.approve.selector, spender, value)
);
}
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
_callOptionalReturn(
token,
abi.encodeWithSelector(
token.approve.selector,
spender,
oldAllowance + value
)
);
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(
oldAllowance >= value,
"SafeERC20: decreased allowance below zero"
);
_callOptionalReturn(
token,
abi.encodeWithSelector(
token.approve.selector,
spender,
oldAllowance - value
)
);
}
}
function forceApprove(
IERC20 token,
address spender,
uint256 value
) internal {
bytes memory approvalCall = abi.encodeWithSelector(
token.approve.selector,
spender,
value
);
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(
token,
abi.encodeWithSelector(token.approve.selector, spender, 0)
);
_callOptionalReturn(token, approvalCall);
}
}
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(
nonceAfter == nonceBefore + 1,
"SafeERC20: permit did not succeed"
);
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(
data,
"SafeERC20: low-level call failed"
);
require(
returndata.length == 0 || abi.decode(returndata, (bool)),
"SafeERC20: ERC20 operation did not succeed"
);
}
function _callOptionalReturnBool(
IERC20 token,
bytes memory data
) private returns (bool) {
(bool success, bytes memory returndata) = address(token).call(data);
return
success &&
(returndata.length == 0 || abi.decode(returndata, (bool))) &&
Address.isContract(address(token));
}
}
interface IERC20Metadata is IERC20 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
}
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
}
function _nonReentrantAfter() private {
_status = _NOT_ENTERED;
}
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == _ENTERED;
}
}
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
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 to,
uint256 amount
) public virtual override returns (bool) {
address owner = _msgSender();
_transfer(owner, to, 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) {
address owner = _msgSender();
_approve(owner, spender, amount);
return true;
}
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;
}
function increaseAllowance(
address spender,
uint256 addedValue
) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, allowance(owner, spender) + addedValue);
return true;
}
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;
}
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;
_balances[to] += amount;
}
emit Transfer(from, to, amount);
_afterTokenTransfer(from, to, amount);
}
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 {
_balances[account] += amount;
}
emit Transfer(address(0), account, amount);
_afterTokenTransfer(address(0), account, amount);
}
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;
_totalSupply -= amount;
}
emit Transfer(account, address(0), amount);
_afterTokenTransfer(account, address(0), 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 _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);
}
}
}
function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
function _afterTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
}
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);
constructor() {
_transferOwnership(_msgSender());
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(
newOwner != address(0),
"Ownable: new owner is the zero address"
);
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
library SafeMath {
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
function sub(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
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;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
function div(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
require(b > 0, errorMessage);
uint256 c = a / b;
return c;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
function mod(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}
library SafeMathInt {
int256 private constant MIN_INT256 = int256(1) << 255;
int256 private constant MAX_INT256 = ~(int256(1) << 255);
function mul(int256 a, int256 b) internal pure returns (int256) {
int256 c = a * b;
require(c != MIN_INT256 || (a & MIN_INT256) != (b & MIN_INT256));
require((b == 0) || (c / b == a));
return c;
}
function div(int256 a, int256 b) internal pure returns (int256) {
require(b != -1 || a != MIN_INT256);
return a / b;
}
function sub(int256 a, int256 b) internal pure returns (int256) {
int256 c = a - b;
require((b >= 0 && c <= a) || (b < 0 && c > a));
return c;
}
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 abs(int256 a) internal pure returns (int256) {
require(a != MIN_INT256);
return a < 0 ? -a : a;
}
function toUint256Safe(int256 a) internal pure returns (uint256) {
require(a >= 0);
return uint256(a);
}
}
library SafeMathUint {
function toInt256Safe(uint256 a) internal pure returns (int256) {
int256 b = int256(a);
require(b >= 0);
return b;
}
}
library IterableMapping {
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();
}
}
interface DividendPayingTokenInterface {
function dividendOf(address _owner) external view returns (uint256);
function withdrawDividend() external;
event DividendsDistributed(address indexed from, uint256 weiAmount);
event DividendWithdrawn(address indexed to, uint256 weiAmount);
}
interface DividendPayingTokenOptionalInterface {
function withdrawableDividendOf(
address _owner
) external view returns (uint256);
function withdrawnDividendOf(
address _owner
) external view returns (uint256);
function accumulativeDividendOf(
address _owner
) external view returns (uint256);
}
contract DividendPayingToken is
ERC20,
Ownable,
DividendPayingTokenInterface,
DividendPayingTokenOptionalInterface,
ReentrancyGuard
{
using SafeMath for uint256;
using SafeMathUint for uint256;
using SafeMathInt for int256;
uint256 internal constant magnitude = 2 ** 128;
uint256 internal magnifiedDividendPerShare;
uint256 public totalDividendsDistributed;
address public immutable rewardToken;
mapping(address => int256) internal magnifiedDividendCorrections;
mapping(address => uint256) internal withdrawnDividends;
constructor(
string memory _name,
string memory _symbol,
address _rewardToken
) ERC20(_name, _symbol) {
rewardToken = _rewardToken;
}
function distributeDividends(uint256 amount) public onlyOwner {
require(totalSupply() > 0);
if (amount > 0) {
magnifiedDividendPerShare = magnifiedDividendPerShare.add(
(amount).mul(magnitude) / totalSupply()
);
emit DividendsDistributed(msg.sender, amount);
totalDividendsDistributed = totalDividendsDistributed.add(amount);
}
}
function withdrawDividend() public virtual override {
_withdrawDividendOfUser(payable(msg.sender));
}
function _withdrawDividendOfUser(
address payable user
) internal nonReentrant returns (uint256) {
uint256 _withdrawableDividend = withdrawableDividendOf(user);
if (_withdrawableDividend > 0) {
withdrawnDividends[user] = withdrawnDividends[user].add(
_withdrawableDividend
);
emit DividendWithdrawn(user, _withdrawableDividend);
bool success = IERC20(rewardToken).transfer(
user,
_withdrawableDividend
);
if (!success) {
withdrawnDividends[user] = withdrawnDividends[user].sub(
_withdrawableDividend
);
return 0;
}
return _withdrawableDividend;
}
return 0;
}
function dividendOf(address _owner) public view override returns (uint256) {
return withdrawableDividendOf(_owner);
}
function withdrawableDividendOf(
address _owner
) public view override returns (uint256) {
return accumulativeDividendOf(_owner).sub(withdrawnDividends[_owner]);
}
function withdrawnDividendOf(
address _owner
) public view override returns (uint256) {
return withdrawnDividends[_owner];
}
function accumulativeDividendOf(
address _owner
) public view override returns (uint256) {
return
magnifiedDividendPerShare
.mul(balanceOf(_owner))
.toInt256Safe()
.add(magnifiedDividendCorrections[_owner])
.toUint256Safe() / magnitude;
}
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
);
}
function _mint(address account, uint256 value) internal override {
super._mint(account, value);
magnifiedDividendCorrections[account] = magnifiedDividendCorrections[
account
].sub((magnifiedDividendPerShare.mul(value)).toInt256Safe());
}
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);
}
}
}
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;
uint256 public minimumDividendForAutoClaim;
event ExcludeFromDividends(address indexed account);
event ClaimWaitUpdated(uint256 indexed newValue, uint256 indexed oldValue);
event Claim(
address indexed account,
uint256 amount,
bool indexed automatic
);
constructor(
uint256 minBalance,
uint256 minDividend,
address _rewardToken
) DividendPayingToken("Reward Tracker", "DividendTracker", _rewardToken) {
claimWait = 3600;
minimumTokenBalanceForDividends = minBalance;
minimumDividendForAutoClaim = minDividend;
}
receive() external payable {}
fallback() external payable {}
function _transfer(address, address, uint256) internal pure override {
require(false, "No transfers allowed");
}
function withdrawDividend() public pure override {
require(
false,
"withdrawDividend disabled. Use the 'claim' function on the main contract."
);
}
function updateMinimumTokenBalanceForDividends(
uint256 _newMinimumBalance
) external onlyOwner {
require(
_newMinimumBalance != minimumTokenBalanceForDividends,
"New mimimum balance for dividend cannot be same as current minimum balance"
);
minimumTokenBalanceForDividends = _newMinimumBalance;
}
function updateMinimumDividendForAutoClaim(
uint256 _newMinimumDividend
) external onlyOwner {
require(
_newMinimumDividend != minimumDividendForAutoClaim,
"New mimimum dividend for auto claim cannot be same as current minimum dividend"
);
minimumDividendForAutoClaim = _newMinimumDividend;
}
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 >= 3_600 && newClaimWait <= 86_400,
"claimWait must be updated to between 1 and 24 hours"
);
require(
newClaimWait != claimWait,
"Cannot update claimWait to same value"
);
emit ClaimWaitUpdated(newClaimWait, claimWait);
claimWait = newClaimWait;
}
function setLastProcessedIndex(uint256 index) external onlyOwner {
lastProcessedIndex = index;
}
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) public returns (uint256, uint256, uint256) {
uint256 numberOfTokenHolders = tokenHoldersMap.keys.length;
if (numberOfTokenHolders == 0) {
return (0, 0, lastProcessedIndex);
}
uint256 _lastProcessedIndex = lastProcessedIndex;
uint256 gasUsed = 0;
uint256 gasLeft = gasleft();
uint256 iterations = 0;
uint256 claims = 0;
while (gasUsed < gas && iterations < numberOfTokenHolders) {
_lastProcessedIndex++;
if (_lastProcessedIndex >= tokenHoldersMap.keys.length) {
_lastProcessedIndex = 0;
}
address account = tokenHoldersMap.keys[_lastProcessedIndex];
if (
canAutoClaim(lastClaimTimes[account]) &&
withdrawableDividendOf(account) >= minimumDividendForAutoClaim
) {
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;
}
}
contract PIVOT is Ownable, ReentrancyGuard, ERC20 {
using SafeERC20 for IERC20;
uint256 public burnTaxBuy;
uint256 public burnTaxSell;
uint256 public buybackTaxBuy;
uint256 public buybackTaxSell;
uint256 public liquidityTaxBuy;
uint256 public liquidityTaxSell;
uint256 public marketingTaxBuy;
uint256 public marketingTaxSell;
uint256 public reflectionTaxBuy;
uint256 public reflectionTaxSell;
uint256 public immutable denominator;
uint256 public buybackTokenAmount;
uint256 public liquidityTokenAmount;
uint256 public marketingTokenAmount;
uint256 public reflectionTokenAmount;
address public buybackWallet;
address public marketingWallet;
address public immutable reflectionToken;
bool private swapping;
uint256 public swapTokensAtAmount;
bool public isSwapBackEnabled;
IUniswapV2Router02 public immutable uniswapV2Router;
address public immutable uniswapV2Pair;
bool private reflecting;
DividendTracker public dividendTracker;
uint256 public gasForProcessing;
bool public isAutoDistributeEnabled;
uint256 public maxWalletLimit;
mapping(address => bool) private _isAutomatedMarketMakerPair;
mapping(address => bool) private _isExcludedFromFees;
mapping(address => bool) private _isExcludedFromMaxWalletLimit;
modifier inSwap() {
swapping = true;
_;
swapping = false;
}
modifier inReflection() {
reflecting = true;
_;
reflecting = false;
}
event UpdateBuyTax(
uint256 burnTaxBuy,
uint256 buybackTaxBuy,
uint256 liquidityTaxBuy,
uint256 marketingTaxBuy,
uint256 reflectionTaxBuy
);
event UpdateSellTax(
uint256 burnTaxSell,
uint256 buybackTaxSell,
uint256 liquidityTaxSell,
uint256 marketingTaxSell,
uint256 reflectionTaxSell
);
event UpdateBuybackWallet(address indexed buybackWallet);
event UpdateMarketingWallet(address indexed marketingWallet);
event UpdateSwapTokensAtAmount(uint256 swapTokensAtAmount);
event UpdateSwapBackStatus(bool status);
event UpdateDividendTracker(
address indexed newAddress,
address indexed oldAddress
);
event UpdateGasForProcessing(uint256 gasForProcessing);
event UpdateAutoDistributeStatus(bool status);
event UpdateMaxWalletLimit(uint256 maxWalletLimit);
event UpdateAutomatedMarketMakerPair(address indexed pair, bool status);
event UpdateExcludeFromFees(address indexed account, bool isExcluded);
event UpdateExcludeFromMaxWalletLimit(
address indexed account,
bool isExcluded
);
event SendDividends(uint256 amount);
event ProcessedDividendTracker(
uint256 iterations,
uint256 claims,
uint256 lastProcessedIndex,
bool indexed automatic,
uint256 gas,
address indexed processor
);
constructor() ERC20("Pivot Coin", "PIVOT") {
_transferOwnership(0xbdB2Ee7F45E1f386A1a88a8Ad037777b732D2666);
_mint(owner(), 31_400_000_000_000 * (10 ** 18));
burnTaxBuy = 100;
burnTaxSell = 100;
buybackTaxBuy = 100;
buybackTaxSell = 100;
liquidityTaxBuy = 100;
liquidityTaxSell = 100;
marketingTaxBuy = 100;
marketingTaxSell = 100;
reflectionTaxBuy = 100;
reflectionTaxSell = 100;
denominator = 10_000;
buybackWallet = 0xd394D1301Bcf626e60A2930d07855e7f09663e87;
marketingWallet = 0x5dAFC1bB1105482649852cE0d50F73d4ec9bAcE4;
reflectionToken = address(this);
swapTokensAtAmount = totalSupply() / 100_000;
isSwapBackEnabled = true;
address router = getRouterAddress();
uniswapV2Router = IUniswapV2Router02(router);
uniswapV2Pair = IUniswapV2Factory(uniswapV2Router.factory()).createPair(
address(this),
uniswapV2Router.WETH()
);
_approve(address(this), address(uniswapV2Router), type(uint256).max);
dividendTracker = new DividendTracker(
0,
1 * (10 ** 18),
reflectionToken
);
gasForProcessing = 300_000;
isAutoDistributeEnabled = true;
maxWalletLimit = 200;
_isAutomatedMarketMakerPair[address(uniswapV2Pair)] = true;
_isExcludedFromFees[address(dividendTracker)] = true;
_isExcludedFromFees[address(this)] = true;
_isExcludedFromFees[address(uniswapV2Router)] = true;
_isExcludedFromFees[address(owner())] = true;
_isExcludedFromFees[address(0xdead)] = true;
_isExcludedFromMaxWalletLimit[address(0xdead)] = true;
_isExcludedFromMaxWalletLimit[address(owner())] = true;
_isExcludedFromMaxWalletLimit[address(this)] = true;
_isExcludedFromMaxWalletLimit[address(uniswapV2Router)] = true;
_isExcludedFromMaxWalletLimit[address(uniswapV2Pair)] = true;
dividendTracker.excludeFromDividends(address(dividendTracker));
dividendTracker.excludeFromDividends(address(this));
dividendTracker.excludeFromDividends(address(uniswapV2Router));
dividendTracker.excludeFromDividends(address(uniswapV2Pair));
dividendTracker.excludeFromDividends(address(owner()));
dividendTracker.excludeFromDividends(address(0xdead));
}
receive() external payable {}
fallback() external payable {}
function isContract(address account) internal view returns (bool) {
return account.code.length > 0;
}
function getRouterAddress() public view returns (address) {
if (block.chainid == 56) {
return 0x10ED43C718714eb63d5aA57B78B54704E256024E;
} else if (block.chainid == 97) {
return 0xD99D1c33F9fC3444f8101754aBC46c52416550D1;
} else if (block.chainid == 1 || block.chainid == 5) {
return 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
} else {
revert("Cannot found router on this network");
}
}
function claimStuckTokens(address token) external onlyOwner {
require(token != address(this), "Owner cannot claim native tokens");
if (token == address(0x0)) {
payable(msg.sender).transfer(address(this).balance);
return;
}
IERC20 ERC20token = IERC20(token);
uint256 balance = ERC20token.balanceOf(address(this));
ERC20token.safeTransfer(msg.sender, balance);
}
function setBuyTax(
uint256 _burnTaxBuy,
uint256 _buybackTaxBuy,
uint256 _liquidityTaxBuy,
uint256 _marketingTaxBuy,
uint256 _reflectionTaxBuy
) external onlyOwner {
require(
burnTaxBuy != _burnTaxBuy ||
buybackTaxBuy != _buybackTaxBuy ||
liquidityTaxBuy != _liquidityTaxBuy ||
marketingTaxBuy != _marketingTaxBuy ||
reflectionTaxBuy != _reflectionTaxBuy,
"Buy Tax already on that amount"
);
require(
_burnTaxBuy +
_buybackTaxBuy +
_liquidityTaxBuy +
_marketingTaxBuy +
_reflectionTaxBuy <=
1_000,
"Buy Tax cannot be more than 10%"
);
burnTaxBuy = _burnTaxBuy;
buybackTaxBuy = _buybackTaxBuy;
liquidityTaxBuy = _liquidityTaxBuy;
marketingTaxBuy = _marketingTaxBuy;
reflectionTaxBuy = _reflectionTaxBuy;
emit UpdateBuyTax(
_burnTaxBuy,
_buybackTaxBuy,
_liquidityTaxBuy,
_marketingTaxBuy,
_reflectionTaxBuy
);
}
function setSellTax(
uint256 _burnTaxSell,
uint256 _buybackTaxSell,
uint256 _liquidityTaxSell,
uint256 _marketingTaxSell,
uint256 _reflectionTaxSell
) external onlyOwner {
require(
burnTaxSell != _burnTaxSell ||
buybackTaxSell != _buybackTaxSell ||
liquidityTaxSell != _liquidityTaxSell ||
marketingTaxSell != _marketingTaxSell ||
reflectionTaxSell != _reflectionTaxSell,
"Sell Tax already on that amount"
);
require(
_burnTaxSell +
_buybackTaxSell +
_liquidityTaxSell +
_marketingTaxSell +
_reflectionTaxSell <=
1_000,
"Sell Tax cannot be more than 10%"
);
burnTaxSell = _burnTaxSell;
buybackTaxSell = _buybackTaxSell;
liquidityTaxSell = _liquidityTaxSell;
marketingTaxSell = _marketingTaxSell;
reflectionTaxSell = _reflectionTaxSell;
emit UpdateSellTax(
_burnTaxSell,
_buybackTaxSell,
_liquidityTaxSell,
_marketingTaxSell,
_reflectionTaxSell
);
}
function setBuybackWallet(address _buybackWallet) external onlyOwner {
require(
_buybackWallet != buybackWallet,
"Buyback wallet is already that address"
);
require(
_buybackWallet != address(0),
"Buyback wallet cannot be the zero address"
);
require(
!isContract(_buybackWallet),
"Buyback wallet cannot be a contract"
);
buybackWallet = _buybackWallet;
emit UpdateBuybackWallet(_buybackWallet);
}
function setMarketingWallet(address _marketingWallet) external onlyOwner {
require(
_marketingWallet != marketingWallet,
"Marketing wallet is already that address"
);
require(
_marketingWallet != address(0),
"Marketing wallet cannot be the zero address"
);
require(
!isContract(_marketingWallet),
"Marketing wallet cannot be a contract"
);
marketingWallet = _marketingWallet;
emit UpdateMarketingWallet(_marketingWallet);
}
function setSwapTokensAtAmount(uint256 amount) external onlyOwner {
require(
swapTokensAtAmount != amount,
"SwapTokensAtAmount already on that amount"
);
require(
amount >= totalSupply() / 1_000_000,
"Amount must be equal or greater than 0.000001% of Total Supply"
);
swapTokensAtAmount = amount;
emit UpdateSwapTokensAtAmount(amount);
}
function toggleSwapBack(bool status) external onlyOwner {
require(isSwapBackEnabled != status, "SwapBack already on status");
isSwapBackEnabled = status;
emit UpdateSwapBackStatus(status);
}
function setDividendTracker(address newAddress) external onlyOwner {
require(
newAddress != address(dividendTracker),
"The dividend tracker already has that address"
);
DividendTracker newDividendTracker = DividendTracker(
payable(newAddress)
);
require(
newDividendTracker.owner() == address(this),
"The new dividend tracker must be owned by the token contract"
);
try
newDividendTracker.excludeFromDividends(address(newDividendTracker))
{} catch {}
try newDividendTracker.excludeFromDividends(address(this)) {} catch {}
try
newDividendTracker.excludeFromDividends(address(uniswapV2Router))
{} catch {}
try
newDividendTracker.excludeFromDividends(address(uniswapV2Pair))
{} catch {}
try
newDividendTracker.excludeFromDividends(address(owner()))
{} catch {}
emit UpdateDividendTracker(newAddress, address(dividendTracker));
dividendTracker = newDividendTracker;
}
function setGasForProcessing(uint256 newValue) external onlyOwner {
require(
newValue >= 200_000 && newValue <= 500_000,
"gasForProcessing must be between 200,000 and 500,000"
);
require(
newValue != gasForProcessing,
"Cannot update gasForProcessing to same value"
);
emit UpdateGasForProcessing(newValue);
gasForProcessing = newValue;
}
function toggleAutoDistribute(bool status) external onlyOwner {
require(
isAutoDistributeEnabled != status,
"Auto Distribute already on status"
);
isAutoDistributeEnabled = status;
emit UpdateAutoDistributeStatus(status);
}
function setMaxWalletLimit(uint256 amount) external onlyOwner {
require(
maxWalletLimit != amount,
"maxWalletLimit already on that amount"
);
require(
amount >= 10 && amount <= 10_000,
"maxWalletLimit cannot be below 0.1% of totalSupply (10) or more than 100% of totalSupply (10000)"
);
maxWalletLimit = amount;
emit UpdateMaxWalletLimit(amount);
}
function setAutomatedMarketMakerPair(
address pair,
bool status
) external onlyOwner {
require(
_isAutomatedMarketMakerPair[pair] != status,
"Pair address is already the value of 'status'"
);
require(pair != address(uniswapV2Pair), "Cannot set this pair");
_isAutomatedMarketMakerPair[pair] = status;
emit UpdateAutomatedMarketMakerPair(pair, status);
}
function isAutomatedMarketMakerPair(
address pair
) external view returns (bool) {
return _isAutomatedMarketMakerPair[pair];
}
function setExcludeFromFees(
address account,
bool excluded
) external onlyOwner {
require(
_isExcludedFromFees[account] != excluded,
"Account is already the value of 'excluded'"
);
_isExcludedFromFees[account] = excluded;
emit UpdateExcludeFromFees(account, excluded);
}
function isExcludedFromFees(address account) external view returns (bool) {
return _isExcludedFromFees[account];
}
function setExcludeFromMaxWalletLimit(
address account,
bool excluded
) external onlyOwner {
require(
account != address(this),
"State of this contract address cannot be modified"
);
require(
_isExcludedFromMaxWalletLimit[account] != excluded,
"Account is already the value of 'excluded'"
);
require(account != address(uniswapV2Pair), "Cannot set this pair");
_isExcludedFromMaxWalletLimit[account] = excluded;
emit UpdateExcludeFromMaxWalletLimit(account, excluded);
}
function isExcludedFromMaxWalletLimit(
address account
) external view returns (bool) {
return _isExcludedFromMaxWalletLimit[account];
}
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 (amount == 0) {
super._transfer(from, to, 0);
return;
}
if (
!_isExcludedFromFees[from] &&
!_isExcludedFromFees[to] &&
!swapping &&
!reflecting
) {
if (!_isExcludedFromMaxWalletLimit[to]) {
require(
balanceOf(to) + amount <=
(totalSupply() * maxWalletLimit) / denominator,
"Balance of to user cannot more than wallet limit"
);
}
}
uint256 contractTokenBalance = balanceOf(address(this));
bool canSwap = contractTokenBalance >= swapTokensAtAmount;
if (
canSwap &&
!swapping &&
!reflecting &&
_isAutomatedMarketMakerPair[to] &&
isSwapBackEnabled &&
buybackTokenAmount + liquidityTokenAmount + marketingTokenAmount > 0
) {
swapBack();
}
bool takeFee = true;
if (
_isExcludedFromFees[from] ||
_isExcludedFromFees[to] ||
swapping ||
reflecting
) {
takeFee = false;
}
if (takeFee) {
uint256 tempBurnAmount;
uint256 tempBuybackAmount;
uint256 tempLiquidityAmount;
uint256 tempMarketingAmount;
uint256 tempReflectionAmount;
if (_isAutomatedMarketMakerPair[from]) {
tempBurnAmount = (amount * burnTaxBuy) / denominator;
tempBuybackAmount = (amount * buybackTaxBuy) / denominator;
tempLiquidityAmount = (amount * liquidityTaxBuy) / denominator;
tempMarketingAmount = (amount * marketingTaxBuy) / denominator;
tempReflectionAmount =
(amount * reflectionTaxBuy) /
denominator;
} else if (_isAutomatedMarketMakerPair[to]) {
tempBurnAmount = (amount * burnTaxSell) / denominator;
tempBuybackAmount = (amount * buybackTaxSell) / denominator;
tempLiquidityAmount = (amount * liquidityTaxSell) / denominator;
tempMarketingAmount = (amount * marketingTaxSell) / denominator;
tempReflectionAmount =
(amount * reflectionTaxSell) /
denominator;
}
buybackTokenAmount += tempBuybackAmount;
liquidityTokenAmount += tempLiquidityAmount;
marketingTokenAmount += tempMarketingAmount;
reflectionTokenAmount += tempReflectionAmount;
uint256 fees = tempBuybackAmount +
tempLiquidityAmount +
tempMarketingAmount;
if (tempBurnAmount > 0) {
amount -= tempBurnAmount;
super._transfer(from, address(0xdead), tempBurnAmount);
}
if (tempReflectionAmount > 0) {
amount -= tempReflectionAmount;
super._transfer(
from,
address(dividendTracker),
tempReflectionAmount
);
}
if (fees > 0) {
amount -= fees;
super._transfer(from, address(this), fees);
}
if (
reflectionTokenAmount > 0 &&
getTotalSupplyOfDividendTracker() > 0
) {
dividendTracker.distributeDividends(reflectionTokenAmount);
emit SendDividends(reflectionTokenAmount);
reflectionTokenAmount = 0;
}
}
super._transfer(from, to, amount);
if (!reflecting && !swapping) {
processReflection(from, to);
}
}
function processReflection(address from, address to) internal inReflection {
if (!_isAutomatedMarketMakerPair[from]) {
try dividendTracker.processAccount(payable(from), true) {} catch {}
}
try
dividendTracker.setBalance(payable(from), balanceOf(from))
{} catch {}
try dividendTracker.setBalance(payable(to), balanceOf(to)) {} catch {}
if (!swapping && isAutoDistributeEnabled) {
uint256 gas = gasForProcessing;
try dividendTracker.process(gas) returns (
uint256 iterations,
uint256 claims,
uint256 lastProcessedIndex
) {
emit ProcessedDividendTracker(
iterations,
claims,
lastProcessedIndex,
true,
gas,
msg.sender
);
} catch {}
}
}
function swapBack() internal inSwap {
address[] memory path = new address[](2);
path[0] = address(this);
path[1] = uniswapV2Router.WETH();
uint256 contractTokenBalance = balanceOf(address(this));
uint256 totalTax = buybackTokenAmount +
liquidityTokenAmount +
marketingTokenAmount;
uint256 liquifyToken = (contractTokenBalance *
(liquidityTokenAmount / 2)) / totalTax;
uint256 swapBackAmount = contractTokenBalance - liquifyToken;
totalTax -= (liquidityTokenAmount) / 2;
uint256 liquidityTokenRemaining = liquidityTokenAmount -
((liquidityTokenAmount) / 2);
try
uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(
swapBackAmount,
0,
path,
address(this),
block.timestamp
)
{} catch {
return;
}
uint256 newBalance = address(this).balance;
uint256 buybackETH = (newBalance * buybackTokenAmount) / totalTax;
uint256 liquifyETH = (newBalance * liquidityTokenRemaining) / totalTax;
uint256 marketingETH = newBalance - buybackETH - liquifyETH;
if (buybackETH > 0) {
sendBNB(buybackWallet, buybackETH);
}
if (liquifyToken > 0 && liquifyETH > 0) {
try
uniswapV2Router.addLiquidityETH{value: liquifyETH}(
address(this),
liquifyToken,
0,
0,
address(0xdead),
block.timestamp
)
{} catch {}
}
if (marketingETH > 0) {
sendBNB(marketingWallet, marketingETH);
}
buybackTokenAmount = 0;
liquidityTokenAmount = 0;
marketingTokenAmount = 0;
}
function sendBNB(
address _to,
uint256 amount
) internal nonReentrant returns (bool) {
if (address(this).balance < amount) return false;
(bool success, ) = payable(_to).call{value: amount}("");
return success;
}
function manualSwapBack() external {
uint256 contractTokenBalance = balanceOf(address(this));
require(contractTokenBalance > 0, "Cant Swap Back 0 Token!");
swapBack();
}
function updateMinimumBalanceForDividends(
uint256 newMinimumBalance
) external onlyOwner {
dividendTracker.updateMinimumTokenBalanceForDividends(
newMinimumBalance
);
}
function getMinimumTokenBalanceForDividends()
external
view
returns (uint256)
{
return dividendTracker.minimumTokenBalanceForDividends();
}
function updateMinimumDividendForAutoClaim(
uint256 newMinimumBalance
) external onlyOwner {
dividendTracker.updateMinimumDividendForAutoClaim(newMinimumBalance);
}
function getMinimumDividendForAutoClaim() external view returns (uint256) {
return dividendTracker.minimumDividendForAutoClaim();
}
function updateClaimWait(uint256 claimWait) external onlyOwner {
dividendTracker.updateClaimWait(claimWait);
}
function getClaimWait() external view returns (uint256) {
return dividendTracker.claimWait();
}
function getTotalDividendsDistributed() external view returns (uint256) {
return dividendTracker.totalDividendsDistributed();
}
function withdrawableDividendOf(
address account
) public view returns (uint256) {
return dividendTracker.withdrawableDividendOf(account);
}
function dividendTokenBalanceOf(
address account
) public view returns (uint256) {
return dividendTracker.balanceOf(account);
}
function totalRewardsEarned(address account) public view returns (uint256) {
return dividendTracker.accumulativeDividendOf(account);
}
function excludeFromDividends(address account) external onlyOwner {
dividendTracker.excludeFromDividends(account);
}
function getAccountDividendsInfo(
address account
)
external
view
returns (
address,
int256,
int256,
uint256,
uint256,
uint256,
uint256,
uint256
)
{
return dividendTracker.getAccount(account);
}
function getAccountDividendsInfoAtIndex(
uint256 index
)
external
view
returns (
address,
int256,
int256,
uint256,
uint256,
uint256,
uint256,
uint256
)
{
return dividendTracker.getAccountAtIndex(index);
}
function processDividendTracker(uint256 gas) external {
(
uint256 iterations,
uint256 claims,
uint256 lastProcessedIndex
) = dividendTracker.process(gas);
emit ProcessedDividendTracker(
iterations,
claims,
lastProcessedIndex,
false,
gas,
msg.sender
);
}
function claim() external {
dividendTracker.processAccount(payable(msg.sender), false);
}
function claimAddress(address addressClaim) external onlyOwner {
dividendTracker.processAccount(payable(addressClaim), false);
}
function getLastProcessedIndex() external view returns (uint256) {
return dividendTracker.getLastProcessedIndex();
}
function setLastProcessedIndex(uint256 index) external onlyOwner {
dividendTracker.setLastProcessedIndex(index);
}
function getNumberOfDividendTokenHolders() public view returns (uint256) {
return dividendTracker.getNumberOfTokenHolders();
}
function getTotalSupplyOfDividendTracker() public view returns (uint256) {
return dividendTracker.totalSupply();
}
}