Address
0x2924dc56bb4eef50d0d32d8acd6aa7c61afa5dfeCurrent Holdings
$1.16
TXs sent
not counted
First Active
not recorded
Last Active
not recorded
Net worth historyi
4,025 snapshots · to block 27,549,349coverage change 26 Augcoverage change 27 Augcoverage change 27 Augcoverage change 27 Augcoverage change 27 Aug
partial matchDividendDistributorsolc 0.8.20+commit.a1b79de6runtime partial · creation not verified
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
abstract contract ReentrancyGuard {
uint256 private constant NOT_ENTERED = 1;
uint256 private constant ENTERED = 2;
uint256 private _status;
error ReentrancyGuardReentrantCall();
constructor() { _status = NOT_ENTERED; }
modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); }
function _nonReentrantBefore() private {
if (_status == ENTERED) { revert ReentrancyGuardReentrantCall(); }
_status = ENTERED;
}
function _nonReentrantAfter() private { _status = NOT_ENTERED; }
}
abstract contract Context {
function _msgSender() internal view virtual returns (address) { return msg.sender; }
}
abstract contract Ownable is Context {
address private _owner;
error OwnableUnauthorizedAccount(address account);
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor(address initialOwner) {
if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); }
_transferOwnership(initialOwner);
}
modifier onlyOwner() { _checkOwner(); _; }
function owner() public view virtual returns (address) { return _owner; }
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); }
}
function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); }
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); }
_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;
}
}
interface IERC20 {
function totalSupply() external view returns (uint256);
function decimals() external view returns (uint8);
function symbol() external view returns (string memory);
function name() external view returns (string memory);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, 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 sender, address recipient, uint256 amount) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
interface IDEXFactory {
function createPair(address tokenA, address tokenB) external returns (address pair);
}
interface IDEXRouter {
function factory() external pure returns (address);
function WETH() external pure returns (address);
function addLiquidityETH(address token, uint amountTokenDesired, uint amountTokenMin, uint amountETHMin, address to, uint deadline) external payable returns (uint amountToken, uint amountETH, uint liquidity);
function swapExactTokensForETHSupportingFeeOnTransferTokens(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;
}
interface IDividendDistributor {
function setDistributionCriteria(uint256 _minWethPeriod, uint256 _minWethDistribution, uint256 _minWbtcPeriod, uint256 _minWbtcDistribution, uint256 _minPlsxPeriod, uint256 _minPlsxDistribution) external;
function setShare(address shareholder, uint256 amount) external;
function depositForWethReflection() external payable;
function depositForWbtcReflection() external payable;
function depositForPlsxReflection() external payable;
function processWeth(uint256 gas) external;
function processWbtc(uint256 gas) external;
function processPlsx(uint256 gas) external;
function claimDividend() external;
}
contract DividendDistributor is IDividendDistributor {
using SafeMath for uint256;
address _token;
struct Share {
uint256 amount;
uint256 wethTotalExcluded;
uint256 wethTotalRealised;
uint256 wbtcTotalExcluded;
uint256 wbtcTotalRealised;
uint256 plsxTotalExcluded;
uint256 plsxTotalRealised;
}
IERC20 WETH = IERC20(0x02DcdD04e3F455D838cd1249292C58f3B79e3C3C);
IERC20 WBTC = IERC20(0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599);
IERC20 PLSX = IERC20(0x95B303987A60C71504D99Aa1b13B4DA07b0790ab);
IERC20 WPLS = IERC20(0xA1077a294dDE1B09bB078844df40758a5D0f9a27);
address DEAD = 0x0000000000000000000000000000000000000369;
IDEXRouter public router; // Only PulseX V1 router
address[] shareholders;
mapping(address => uint256) shareholderWethIndexes;
mapping(address => uint256) shareholderWethClaims;
mapping(address => uint256) shareholderWbtcIndexes;
mapping(address => uint256) shareholderWbtcClaims;
mapping(address => uint256) shareholderPlsxIndexes;
mapping(address => uint256) shareholderPlsxClaims;
mapping(address => Share) public shares;
uint256 public totalShares;
uint256 currentWethIndex;
uint256 public totalWethDividends;
uint256 public totalWethDistributed;
uint256 public wethDividendsPerShare;
uint256 public wethDividendsPerShareAccuracyFactor = 10 ** 36;
uint256 public minWethPeriod = 1 hours;
uint256 public minWethDistribution = (3 * (10 ** 12));
uint256 currentWbtcIndex;
uint256 public totalWbtcDividends;
uint256 public totalWbtcDistributed;
uint256 public wbtcDividendsPerShare;
uint256 public wbtcDividendsPerShareAccuracyFactor = 10 ** 36;
uint256 public minWbtcPeriod = 1 hours;
uint256 public minWbtcDistribution = 2000;
uint256 currentPlsxIndex;
uint256 public totalPlsxDividends;
uint256 public totalPlsxDistributed;
uint256 public plsxDividendsPerShare;
uint256 public plsxDividendsPerShareAccuracyFactor = 10 ** 36;
uint256 public minPlsxPeriod = 1 hours;
uint256 public minPlsxDistribution = (1 * (10 ** 20));
modifier onlyToken() {
require(msg.sender == _token);
_;
}
constructor() {
router = IDEXRouter(0x98bf93ebf5c380C0e6Ae8e192A7e2AE08edAcc02); // PulseX V1 only
_token = msg.sender;
}
function setDistributionCriteria(
uint256 _minWethPeriod,
uint256 _minWethDistribution,
uint256 _minWbtcPeriod,
uint256 _minWbtcDistribution,
uint256 _minPlsxPeriod,
uint256 _minPlsxDistribution
) external override onlyToken {
minWethPeriod = _minWethPeriod;
minWethDistribution = _minWethDistribution;
minWbtcPeriod = _minWbtcPeriod;
minWbtcDistribution = _minWbtcDistribution;
minPlsxPeriod = _minPlsxPeriod;
minPlsxDistribution = _minPlsxDistribution;
}
function setShare(address shareholder, uint256 amount) external override onlyToken {
if (shares[shareholder].amount > 0) {
distributeWethDividend(shareholder);
distributeWbtcDividend(shareholder);
distributePlsxDividend(shareholder);
}
if (amount > 0 && shares[shareholder].amount == 0) {
addShareholder(shareholder);
} else if (amount == 0 && shares[shareholder].amount > 0) {
removeShareholder(shareholder);
}
totalShares = totalShares.sub(shares[shareholder].amount).add(amount);
shares[shareholder].amount = amount;
shares[shareholder].wethTotalExcluded = getCumulativeWethDividends(shares[shareholder].amount);
shares[shareholder].wbtcTotalExcluded = getCumulativeWbtcDividends(shares[shareholder].amount);
shares[shareholder].plsxTotalExcluded = getCumulativePlsxDividends(shares[shareholder].amount);
}
function depositForWethReflection() external payable override onlyToken {
uint256 wethBalanceBefore = WETH.balanceOf(address(this));
address[] memory path = new address[](2);
path[0] = address(WPLS);
path[1] = address(WETH);
router.swapExactETHForTokensSupportingFeeOnTransferTokens{value: msg.value}(0, path, address(this), block.timestamp);
uint256 wethGained = WETH.balanceOf(address(this)).sub(wethBalanceBefore);
totalWethDividends = totalWethDividends.add(wethGained);
if (totalShares > 0) {
wethDividendsPerShare = wethDividendsPerShare.add(wethDividendsPerShareAccuracyFactor.mul(wethGained).div(totalShares));
}
}
function depositForWbtcReflection() external payable override onlyToken {
uint256 wbtcBalanceBefore = WBTC.balanceOf(address(this));
address[] memory path = new address[](2);
path[0] = address(WPLS);
path[1] = address(WBTC);
router.swapExactETHForTokensSupportingFeeOnTransferTokens{value: msg.value}(0, path, address(this), block.timestamp);
uint256 wbtcGained = WBTC.balanceOf(address(this)).sub(wbtcBalanceBefore);
totalWbtcDividends = totalWbtcDividends.add(wbtcGained);
if (totalShares > 0) {
wbtcDividendsPerShare = wbtcDividendsPerShare.add(wbtcDividendsPerShareAccuracyFactor.mul(wbtcGained).div(totalShares));
}
}
function depositForPlsxReflection() external payable override onlyToken {
uint256 plsxBalanceBefore = PLSX.balanceOf(address(this));
address[] memory path = new address[](2);
path[0] = address(WPLS);
path[1] = address(PLSX);
router.swapExactETHForTokensSupportingFeeOnTransferTokens{value: msg.value}(0, path, address(this), block.timestamp);
uint256 plsxGained = PLSX.balanceOf(address(this)).sub(plsxBalanceBefore);
totalPlsxDividends = totalPlsxDividends.add(plsxGained);
if (totalShares > 0) {
plsxDividendsPerShare = plsxDividendsPerShare.add(plsxDividendsPerShareAccuracyFactor.mul(plsxGained).div(totalShares));
}
}
function distributeWethDividend(address shareholder) internal {
if (shares[shareholder].amount == 0) { return; }
uint256 amount = getUnpaidWethEarnings(shareholder);
if (amount > 0) {
totalWethDistributed = totalWethDistributed.add(amount);
WETH.transfer(shareholder, amount);
shareholderWethClaims[shareholder] = block.timestamp;
shares[shareholder].wethTotalRealised = shares[shareholder].wethTotalRealised.add(amount);
shares[shareholder].wethTotalExcluded = getCumulativeWethDividends(shares[shareholder].amount);
}
}
function distributeWbtcDividend(address shareholder) internal {
if (shares[shareholder].amount == 0) { return; }
uint256 amount = getUnpaidWbtcEarnings(shareholder);
if (amount > 0) {
totalWbtcDistributed = totalWbtcDistributed.add(amount);
WBTC.transfer(shareholder, amount);
shareholderWbtcClaims[shareholder] = block.timestamp;
shares[shareholder].wbtcTotalRealised = shares[shareholder].wbtcTotalRealised.add(amount);
shares[shareholder].wbtcTotalExcluded = getCumulativeWbtcDividends(shares[shareholder].amount);
}
}
function distributePlsxDividend(address shareholder) internal {
if (shares[shareholder].amount == 0) { return; }
uint256 amount = getUnpaidPlsxEarnings(shareholder);
if (amount > 0) {
totalPlsxDistributed = totalPlsxDistributed.add(amount);
PLSX.transfer(shareholder, amount);
shareholderPlsxClaims[shareholder] = block.timestamp;
shares[shareholder].plsxTotalRealised = shares[shareholder].plsxTotalRealised.add(amount);
shares[shareholder].plsxTotalExcluded = getCumulativePlsxDividends(shares[shareholder].amount);
}
}
function processWeth(uint256 gas) external override onlyToken {
uint256 shareholderCount = shareholders.length;
if (shareholderCount == 0) { return; }
uint256 gasUsed = 0;
uint256 gasLeft = gasleft();
uint256 iterations = 0;
while (gasUsed < gas && iterations < shareholderCount) {
if (currentWethIndex >= shareholderCount) {
currentWethIndex = 0;
}
if (shouldWethDistribute(shareholders[currentWethIndex])) {
distributeWethDividend(shareholders[currentWethIndex]);
}
gasUsed = gasUsed.add(gasLeft.sub(gasleft()));
gasLeft = gasleft();
currentWethIndex++;
iterations++;
}
}
function processWbtc(uint256 gas) external override onlyToken {
uint256 shareholderCount = shareholders.length;
if (shareholderCount == 0) { return; }
uint256 gasUsed = 0;
uint256 gasLeft = gasleft();
uint256 iterations = 0;
while (gasUsed < gas && iterations < shareholderCount) {
if (currentWbtcIndex >= shareholderCount) {
currentWbtcIndex = 0;
}
if (shouldWbtcDistribute(shareholders[currentWbtcIndex])) {
distributeWbtcDividend(shareholders[currentWbtcIndex]);
}
gasUsed = gasUsed.add(gasLeft.sub(gasleft()));
gasLeft = gasleft();
currentWbtcIndex++;
iterations++;
}
}
function processPlsx(uint256 gas) external override onlyToken {
uint256 shareholderCount = shareholders.length;
if (shareholderCount == 0) { return; }
uint256 gasUsed = 0;
uint256 gasLeft = gasleft();
uint256 iterations = 0;
while (gasUsed < gas && iterations < shareholderCount) {
if (currentPlsxIndex >= shareholderCount) {
currentPlsxIndex = 0;
}
if (shouldPlsxDistribute(shareholders[currentPlsxIndex])) {
distributePlsxDividend(shareholders[currentPlsxIndex]);
}
gasUsed = gasUsed.add(gasLeft.sub(gasleft()));
gasLeft = gasleft();
currentPlsxIndex++;
iterations++;
}
}
function shouldWethDistribute(address shareholder) internal view returns (bool) {
return shareholderWethClaims[shareholder] + minWethPeriod < block.timestamp && getUnpaidWethEarnings(shareholder) > minWethDistribution;
}
function shouldWbtcDistribute(address shareholder) internal view returns (bool) {
return shareholderWbtcClaims[shareholder] + minWbtcPeriod < block.timestamp && getUnpaidWbtcEarnings(shareholder) > minWbtcDistribution;
}
function shouldPlsxDistribute(address shareholder) internal view returns (bool) {
return shareholderPlsxClaims[shareholder] + minPlsxPeriod < block.timestamp && getUnpaidPlsxEarnings(shareholder) > minPlsxDistribution;
}
function claimDividend() external override {
distributeWethDividend(msg.sender);
distributeWbtcDividend(msg.sender);
distributePlsxDividend(msg.sender);
}
function getUnpaidWethEarnings(address shareholder) public view returns (uint256) {
if (shares[shareholder].amount == 0) { return 0; }
uint256 shareholderTotalDividends = getCumulativeWethDividends(shares[shareholder].amount);
uint256 shareholderTotalExcluded = shares[shareholder].wethTotalExcluded;
if (shareholderTotalDividends <= shareholderTotalExcluded) { return 0; }
return shareholderTotalDividends.sub(shareholderTotalExcluded);
}
function getUnpaidWbtcEarnings(address shareholder) public view returns (uint256) {
if (shares[shareholder].amount == 0) { return 0; }
uint256 shareholderTotalDividends = getCumulativeWbtcDividends(shares[shareholder].amount);
uint256 shareholderTotalExcluded = shares[shareholder].wbtcTotalExcluded;
if (shareholderTotalDividends <= shareholderTotalExcluded) { return 0; }
return shareholderTotalDividends.sub(shareholderTotalExcluded);
}
function getUnpaidPlsxEarnings(address shareholder) public view returns (uint256) {
if (shares[shareholder].amount == 0) { return 0; }
uint256 shareholderTotalDividends = getCumulativePlsxDividends(shares[shareholder].amount);
uint256 shareholderTotalExcluded = shares[shareholder].plsxTotalExcluded;
if (shareholderTotalDividends <= shareholderTotalExcluded) { return 0; }
return shareholderTotalDividends.sub(shareholderTotalExcluded);
}
// NEW GETTERS FOR REALISED (CLAIMED) AMOUNTS
function getWethTotalRealised(address shareholder) public view returns (uint256) {
return shares[shareholder].wethTotalRealised;
}
function getWbtcTotalRealised(address shareholder) public view returns (uint256) {
return shares[shareholder].wbtcTotalRealised;
}
function getPlsxTotalRealised(address shareholder) public view returns (uint256) {
return shares[shareholder].plsxTotalRealised;
}
function getCumulativeWethDividends(uint256 share) internal view returns (uint256) {
return share.mul(wethDividendsPerShare).div(wethDividendsPerShareAccuracyFactor);
}
function getCumulativeWbtcDividends(uint256 share) internal view returns (uint256) {
return share.mul(wbtcDividendsPerShare).div(wbtcDividendsPerShareAccuracyFactor);
}
function getCumulativePlsxDividends(uint256 share) internal view returns (uint256) {
return share.mul(plsxDividendsPerShare).div(plsxDividendsPerShareAccuracyFactor);
}
function addShareholder(address shareholder) internal {
shareholderWethIndexes[shareholder] = shareholders.length;
shareholderWbtcIndexes[shareholder] = shareholders.length;
shareholderPlsxIndexes[shareholder] = shareholders.length;
shareholders.push(shareholder);
}
function removeShareholder(address shareholder) internal {
shareholders[shareholderWethIndexes[shareholder]] = shareholders[shareholders.length - 1];
shareholderWethIndexes[shareholders[shareholders.length - 1]] = shareholderWethIndexes[shareholder];
shareholders[shareholderWbtcIndexes[shareholder]] = shareholders[shareholders.length - 1];
shareholderWbtcIndexes[shareholders[shareholders.length - 1]] = shareholderWbtcIndexes[shareholder];
shareholders[shareholderPlsxIndexes[shareholder]] = shareholders[shareholders.length - 1];
shareholderPlsxIndexes[shareholders[shareholders.length - 1]] = shareholderPlsxIndexes[shareholder];
shareholders.pop();
}
receive() external payable {}
}
contract CODA is IERC20, ReentrancyGuard, Ownable {
using SafeMath for uint256;
address WPLS = 0xA1077a294dDE1B09bB078844df40758a5D0f9a27;
address WETH = 0x02DcdD04e3F455D838cd1249292C58f3B79e3C3C;
address PLSX = 0x95B303987A60C71504D99Aa1b13B4DA07b0790ab;
address WBTC = 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599;
address DEAD = 0x0000000000000000000000000000000000000369;
string constant _name = "CODA";
string constant _symbol = "CODA";
uint8 constant _decimals = 18;
uint256 _totalSupply = 50_000_000_000e18;
uint256 public _maxTxAmount = _totalSupply;
mapping(address => uint256) _balances;
mapping(address => mapping(address => uint256)) _allowances;
mapping(address => bool) public isFeeExempt;
mapping(address => bool) public isTxLimitExempt;
mapping(address => bool) public isDividendExempt;
uint256 public codaBurnFee = 0;
uint256 public wethReflectionFee = 200;
uint256 public wbtcReflectionFee = 200;
uint256 public plsxReflectionFee = 200;
uint256 public liquidityFee = 100;
uint256 public totalBuyFee = 700;
uint256 public totalSellFee = 700;
uint256 feeDenominator = 10000;
bool public feesOnNormalTransfers = false;
address public autoLiquidityReceiver = 0x2694f6cB721396256418f33f68700c9a7029A9c1;
IDEXRouter public router; // Only PulseX V1
address public pair;
address[] public pairs;
uint256 public launchedAt;
DividendDistributor public distributor;
uint256 distributorWethGas = 500000;
uint256 distributorWbtcGas = 500000;
uint256 distributorPlsxGas = 500000;
bool public swapEnabled = true;
uint256 public swapThreshold = _totalSupply / 5000;
bool inSwap;
modifier swapping() { inSwap = true; _; inSwap = false; }
uint256 public totalCodaBurned;
uint256 public totalPlsLpAdded;
uint256 public totalCodaLpAdded;
constructor() Ownable(msg.sender) {
router = IDEXRouter(0x98bf93ebf5c380C0e6Ae8e192A7e2AE08edAcc02); // PulseX V1 only
pair = IDEXFactory(router.factory()).createPair(WPLS, address(this));
_allowances[address(this)][address(router)] = type(uint256).max;
pairs.push(pair);
distributor = new DividendDistributor();
address owner_ = msg.sender;
isFeeExempt[owner_] = true;
isTxLimitExempt[owner_] = true;
isDividendExempt[pair] = true;
isDividendExempt[address(this)] = true;
isFeeExempt[address(this)] = true;
isTxLimitExempt[address(this)] = true;
isDividendExempt[DEAD] = true;
_balances[owner_] = _totalSupply;
emit Transfer(address(0), owner_, _totalSupply);
}
receive() external payable {}
function totalSupply() external view override returns (uint256) { return _totalSupply; }
function decimals() external pure override returns (uint8) { return _decimals; }
function symbol() external pure override returns (string memory) { return _symbol; }
function name() external pure override returns (string memory) { return _name; }
function balanceOf(address account) public view override returns (uint256) { return _balances[account]; }
function allowance(address holder, address spender) external view override returns (uint256) { return _allowances[holder][spender]; }
function approve(address spender, uint256 amount) public override returns (bool) {
_allowances[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function transfer(address recipient, uint256 amount) external override returns (bool) {
return _transferFrom(msg.sender, recipient, amount);
}
function transferFrom(address sender, address recipient, uint256 amount) external override returns (bool) {
if (_allowances[sender][msg.sender] != ~uint256(0)) {
_allowances[sender][msg.sender] = _allowances[sender][msg.sender].sub(amount, "Insufficient Allowance");
}
return _transferFrom(sender, recipient, amount);
}
function _transferFrom(address sender, address recipient, uint256 amount) internal returns (bool) {
require(launchedAt > 0 || tx.origin == owner(), "The contract is not launched yet");
if (inSwap) { return _basicTransfer(sender, recipient, amount); }
checkTxLimit(sender, recipient, amount);
if (shouldSwapBack()) { swapBack(); }
_balances[sender] = _balances[sender].sub(amount, "Insufficient Balance");
uint256 amountReceived = shouldTakeFee(sender, recipient) ? takeFee(sender, recipient, amount) : amount;
_balances[recipient] = _balances[recipient].add(amountReceived);
if (!isDividendExempt[sender]) {
try distributor.setShare(sender, _balances[sender]) {} catch {}
}
if (!isDividendExempt[recipient]) {
try distributor.setShare(recipient, _balances[recipient]) {} catch {}
}
try distributor.processWeth(distributorWethGas) {} catch {}
try distributor.processWbtc(distributorWbtcGas) {} catch {}
try distributor.processPlsx(distributorPlsxGas) {} catch {}
emit Transfer(sender, recipient, amountReceived);
return true;
}
function _basicTransfer(address sender, address recipient, uint256 amount) internal returns (bool) {
_balances[sender] = _balances[sender].sub(amount, "Insufficient Balance");
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, amount);
return true;
}
function checkTxLimit(address sender, address recipient, uint256 amount) internal view {
require(amount <= _maxTxAmount || isTxLimitExempt[sender] || isTxLimitExempt[recipient], "TX Limit Exceeded");
}
function shouldTakeFee(address sender, address recipient) internal view returns (bool) {
if (isFeeExempt[sender] || isFeeExempt[recipient] || launchedAt == 0) return false;
address[] memory liqPairs = pairs;
for (uint256 i = 0; i < liqPairs.length; i++) {
if (sender == liqPairs[i] || recipient == liqPairs[i]) return true;
}
return feesOnNormalTransfers;
}
function getTotalFee(bool selling) public view returns (uint256) {
if (launchedAt == 0) { return feeDenominator.sub(1); }
return selling ? totalSellFee : totalBuyFee;
}
function takeFee(address sender, address recipient, uint256 amount) internal returns (uint256) {
uint256 feeAmount = amount.mul(getTotalFee(isSell(recipient))).div(feeDenominator);
_balances[address(this)] = _balances[address(this)].add(feeAmount);
emit Transfer(sender, address(this), feeAmount);
return amount.sub(feeAmount);
}
function isSell(address recipient) internal view returns (bool) {
address[] memory liqPairs = pairs;
for (uint256 i = 0; i < liqPairs.length; i++) {
if (recipient == liqPairs[i]) return true;
}
return false;
}
function shouldSwapBack() internal view returns (bool) {
return msg.sender != pair && !inSwap && swapEnabled && _balances[address(this)] >= swapThreshold;
}
function swapBack() internal swapping {
uint256 totalIndividualFees = codaBurnFee.add(wethReflectionFee).add(wbtcReflectionFee).add(plsxReflectionFee).add(liquidityFee);
uint256 amountCodaLiquidity = swapThreshold.mul(liquidityFee).div(totalIndividualFees).div(2);
uint256 amountCodaBurn = swapThreshold.mul(codaBurnFee).div(totalIndividualFees);
if (amountCodaBurn > 0) {
_basicTransfer(address(this), DEAD, amountCodaBurn);
totalCodaBurned = totalCodaBurned.add(amountCodaBurn);
}
uint256 amountCodaSwap = swapThreshold.sub(amountCodaLiquidity).sub(amountCodaBurn);
uint256 balanceBefore = address(this).balance;
address[] memory path = new address[](2);
path[0] = address(this);
path[1] = address(WPLS);
try router.swapExactTokensForETHSupportingFeeOnTransferTokens(amountCodaSwap, 0, path, address(this), block.timestamp) {
uint256 amountPls = address(this).balance.sub(balanceBefore);
uint256 totalSwapFees = wethReflectionFee + wbtcReflectionFee + plsxReflectionFee + (liquidityFee / 2);
uint256 amountPlsLiquidity = amountPls.mul(liquidityFee).div(totalSwapFees).div(2);
uint256 amountWethReflection = amountPls.mul(wethReflectionFee).div(totalSwapFees);
uint256 amountWbtcReflection = amountPls.mul(wbtcReflectionFee).div(totalSwapFees);
uint256 amountPlsxReflection = amountPls.mul(plsxReflectionFee).div(totalSwapFees);
if (amountCodaLiquidity > 0) {
try router.addLiquidityETH{value: amountPlsLiquidity}(address(this), amountCodaLiquidity, 0, amountPlsLiquidity, autoLiquidityReceiver, block.timestamp) {
totalPlsLpAdded = totalPlsLpAdded.add(amountPlsLiquidity);
totalCodaLpAdded = totalCodaLpAdded.add(amountCodaLiquidity);
emit AutoLiquify(amountCodaLiquidity, amountPlsLiquidity);
} catch {
emit AutoLiquify(0, 0);
}
}
if (amountWethReflection > 0) {
try distributor.depositForWethReflection{value: amountWethReflection}() {} catch {}
}
if (amountWbtcReflection > 0) {
try distributor.depositForWbtcReflection{value: amountWbtcReflection}() {} catch {}
}
if (amountPlsxReflection > 0) {
try distributor.depositForPlsxReflection{value: amountPlsxReflection}() {} catch {}
}
if (address(this).balance > 0) {
(bool success, ) = payable(owner()).call{value: address(this).balance, gas: 30000}("");
success;
}
emit SwapBackSuccess(amountCodaSwap);
} catch Error(string memory e) {
emit SwapBackFailed(string(abi.encodePacked("SwapBack failed with error ", e)));
} catch {
emit SwapBackFailed("SwapBack failed without an error message from PulseX");
}
}
function launch() external onlyOwner {
require(launchedAt == 0, "Already launched.");
launchedAt = block.timestamp;
emit Launched(block.number, block.timestamp);
}
function setTxLimit(uint256 amount) external onlyOwner {
require(amount >= _totalSupply / 2000);
_maxTxAmount = amount;
}
function setIsDividendExempt(address holder, bool exempt) external onlyOwner {
require(holder != address(this) && holder != pair);
isDividendExempt[holder] = exempt;
if (exempt) {
distributor.setShare(holder, 0);
} else {
distributor.setShare(holder, _balances[holder]);
}
}
function setIsFeeExempt(address holder, bool exempt) external onlyOwner {
isFeeExempt[holder] = exempt;
}
function setIsTxLimitExempt(address holder, bool exempt) external onlyOwner {
isTxLimitExempt[holder] = exempt;
}
function setFees(
uint256 _codaBurnFee,
uint256 _wethReflectionFee,
uint256 _wbtcReflectionFee,
uint256 _plsxReflectionFee,
uint256 _liquidityFee,
bool _feesOnNormalTransfers
) external onlyOwner {
require(_codaBurnFee <= 100, "Burn fee cannot exceed 1%");
require(_wethReflectionFee <= 300, "WETH reflection fee cannot exceed 3%");
require(_wbtcReflectionFee <= 300, "pWBTC reflection fee cannot exceed 3%");
require(_plsxReflectionFee <= 300, "PLSX reflection fee cannot exceed 3%");
require(_liquidityFee <= 200, "Liquidity fee cannot exceed 2%");
codaBurnFee = _codaBurnFee;
wethReflectionFee = _wethReflectionFee;
wbtcReflectionFee = _wbtcReflectionFee;
plsxReflectionFee = _plsxReflectionFee;
liquidityFee = _liquidityFee;
uint256 total = codaBurnFee.add(wethReflectionFee).add(wbtcReflectionFee).add(plsxReflectionFee).add(liquidityFee);
totalBuyFee = total;
totalSellFee = total;
require(total <= feeDenominator, "Total fees cannot exceed 10%");
feesOnNormalTransfers = _feesOnNormalTransfers;
emit ParameterUpdated();
}
function setLiquidityFeeReceiver(address _autoLiquidityReceiver) external onlyOwner {
autoLiquidityReceiver = _autoLiquidityReceiver;
emit ParameterUpdated();
}
function setSwapBackSettings(bool _enabled, uint256 _amount) external onlyOwner {
swapEnabled = _enabled;
swapThreshold = _amount;
emit ParameterUpdated();
}
function setDistributionCriteria(
uint256 _minWethPeriod,
uint256 _minWethDistribution,
uint256 _minWbtcPeriod,
uint256 _minWbtcDistribution,
uint256 _minPlsxPeriod,
uint256 _minPlsxDistribution
) external onlyOwner {
distributor.setDistributionCriteria(_minWethPeriod, _minWethDistribution, _minWbtcPeriod, _minWbtcDistribution, _minPlsxPeriod, _minPlsxDistribution);
emit ParameterUpdated();
}
function setDistributorSettings(uint256 wethGas, uint256 wbtcGas, uint256 plsxGas) external onlyOwner {
distributorWethGas = wethGas;
distributorWbtcGas = wbtcGas;
distributorPlsxGas = plsxGas;
require(distributorWethGas <= 1000000 && distributorWbtcGas <= 1000000 && distributorPlsxGas <= 1000000, "Max gas is 1000000");
emit ParameterUpdated();
}
function getCirculatingSupply() public view returns (uint256) {
return _totalSupply.sub(balanceOf(DEAD));
}
function claimDividend() external {
distributor.claimDividend();
}
// PER-WALLET TOTAL EARNED TRACKING
function getTotalWethEarned(address holder) public view returns (uint256) {
return distributor.getUnpaidWethEarnings(holder) + distributor.getWethTotalRealised(holder);
}
function getTotalWbtcEarned(address holder) public view returns (uint256) {
return distributor.getUnpaidWbtcEarnings(holder) + distributor.getWbtcTotalRealised(holder);
}
function getTotalPlsxEarned(address holder) public view returns (uint256) {
return distributor.getUnpaidPlsxEarnings(holder) + distributor.getPlsxTotalRealised(holder);
}
function addPair(address newPair) external onlyOwner {
pairs.push(newPair);
emit ParameterUpdated();
}
function removeLastPair() external onlyOwner {
pairs.pop();
emit ParameterUpdated();
}
event AutoLiquify(uint256 amountCoda, uint256 amountPLS);
event Launched(uint256 blockNumber, uint256 timestamp);
event ParameterUpdated();
event SwapBackSuccess(uint256 amount);
event SwapBackFailed(string message);
}