// SPDX-License-Identifier: MITpragmasolidity 0.8.25;import"./CF_Common.sol";
import"./CF_Ownable.sol";
abstractcontractCF_MaxBalanceisCF_Common, CF_Ownable{
eventSetMaxBalancePercent(uint24 percent);
eventRenouncedMaxBalance();
/// @notice Permanently renounce and prevent the owner from being able to update the max. balance/// @dev Existing settings will continue to be effectivefunctionrenounceMaxBalance() externalonlyOwner{
_renounced.MaxBalance =true;
emit RenouncedMaxBalance();
}
/// @notice Percentage of the max. balance per wallet, depending on total supplyfunctiongetMaxBalancePercent() externalviewreturns (uint24) {
return _maxBalancePercent;
}
/// @notice Set the max. percentage of a wallet balance, depending on total supply/// @param percent Desired percentage, multiplied by denominator (min. 0.1% of total supply)functionsetMaxBalancePercent(uint24 percent) externalonlyOwner{
require(!_renounced.MaxBalance);
_setMaxBalancePercent(percent);
emit SetMaxBalancePercent(percent);
}
function_setMaxBalancePercent(uint24 percent) internal{
unchecked {
require(percent >=100&& percent <=100* _denominator);
}
_maxBalancePercent = percent;
_maxBalanceAmount = _percentage(_totalSupply, uint256(percent));
if (!_initialized) { emit SetMaxBalancePercent(percent); }
}
}
// SPDX-License-Identifier: MITpragmasolidity 0.8.25;import"./CF_Common.sol";
import"./CF_Ownable.sol";
abstractcontractCF_RecoverableisCF_Common, CF_Ownable{
/// @notice Recovers a misplaced amount of an ERC-20 token sitting in the contract balance/// @dev Beware of scam tokens!/// @dev Note that if the token of this contract is specified, amounts allocated for tax distribution and liquidity are reserved/// @param token Address of the ERC-20 token/// @param to Recipient/// @param amount Amount to be transferredfunctionrecoverERC20(address token, address to, uint256 amount) externalonlyOwner{
unchecked {
uint256 balance = IERC20(token).balanceOf(address(this));
uint256 allocated = token ==address(this) ? _amountForTaxDistribution + _amountForLiquidity : (address(_taxToken) == token ? _tokensForTaxDistribution[address(_taxToken)] : 0);
require(balance - (allocated >= balance ? balance : allocated) >= amount, "Exceeds balance");
}
IERC20(token).transfer(to, amount);
}
/// @notice Recovers a misplaced ERC-721 (NFT) sitting in the contract/// @dev Beware of scam tokens!/// @param token Address of the ERC-721 token/// @param to Recipient/// @param tokenId Unique identifier of the NFTfunctionrecoverERC721(address token, address to, uint256 tokenId) externalonlyOwner{
IERC721(token).safeTransferFrom(address(this), to, tokenId);
}
/// @notice Recovers a misplaced amount of native tokens sitting in the contract balance/// @dev Note that if the reflection token is the wrapped native, amounts allocated for tax distribution and/or liquidity are reserved/// @param to Recipient/// @param amount Amount of native tokens to be transferredfunctionrecoverNative(addresspayable to, uint256 amount) externalonlyOwner{
unchecked {
uint256 balance =address(this).balance;
uint256 allocated =address(_taxToken) == _dex.WETH ? _ethForTaxDistribution : 0;
require(balance - (allocated >= balance ? balance : allocated) >= amount, "Exceeds balance");
}
(bool success, ) = to.call{ value: amount }("");
require(success);
}
}
Contract Source Code
File 9 of 13: CF_Taxable.sol
// SPDX-License-Identifier: MITpragmasolidity 0.8.25;import"./CF_Common.sol";
import"./CF_Ownable.sol";
import"./CF_ERC20.sol";
abstractcontractCF_TaxableisCF_Common, CF_Ownable, CF_ERC20{
eventSetTaxBeneficiary(uint8 slot, address account, uint24[3] percent, uint24[3] penalty);
eventSetEarlyPenaltyTime(uint32 time);
eventTaxDistributed(uint256 amount);
eventRenouncedTaxable();
structtaxBeneficiaryView {
address account;
uint24[3] percent;
uint24[3] penalty;
uint256 unclaimed;
}
modifierlockDistributing{
_distributing =true;
_;
_distributing =false;
}
/// @notice Permanently renounce and prevent the owner from being able to update the tax features/// @dev Existing settings will continue to be effectivefunctionrenounceTaxable() externalonlyOwner{
_renounced.Taxable =true;
emit RenouncedTaxable();
}
/// @notice Total amount of taxes collected so farfunctiontotalTaxCollected() externalviewreturns (uint256) {
return _totalTaxCollected;
}
/// @notice Tax applied per transfer/// @dev Taking in consideration your wallet addressfunctiontxTax() externalviewreturns (uint24) {
return txTax(msg.sender);
}
/// @notice Tax applied per transfer/// @param from Sender addressfunctiontxTax(addressfrom) publicviewreturns (uint24) {
unchecked {
returnfrom==address(this) || _whitelisted[from] ||from== _dex.pair ? 0 : (_holder[from].penalty || _tradingEnabled + _earlyPenaltyTime >= _timestamp() ? _totalPenaltyTxTax : _totalTxTax);
}
}
/// @notice Tax applied for buying/// @dev Taking in consideration your wallet addressfunctionbuyTax() externalviewreturns (uint24) {
return buyTax(msg.sender);
}
/// @notice Tax applied for buying/// @param from Buyer's addressfunctionbuyTax(addressfrom) publicviewreturns (uint24) {
if (_suspendTaxes) { return0; }
unchecked {
returnfrom==address(this) || _whitelisted[from] ||from== _dex.pair ? 0 : (_holder[from].penalty || _tradingEnabled + _earlyPenaltyTime >= _timestamp() ? _totalPenaltyBuyTax : _totalBuyTax);
}
}
/// @notice Tax applied for selling/// @dev Taking in consideration your wallet addressfunctionsellTax() externalviewreturns (uint24) {
return sellTax(msg.sender);
}
/// @notice Tax applied for selling/// @param to Seller's addressfunctionsellTax(address to) publicviewreturns (uint24) {
if (_suspendTaxes) { return0; }
unchecked {
return to ==address(this) || _whitelisted[to] || to == _dex.pair || to == _dex.router ? 0 : (_holder[to].penalty || _tradingEnabled + _earlyPenaltyTime >= _timestamp() ? _totalPenaltySellTax : _totalSellTax);
}
}
/// @notice List of all tax beneficiaries and their assigned percentage, according to type of transfer/// @custom:return `list[].account` Beneficiary address/// @custom:return `list[].percent[3]` Index 0 is for tx tax, 1 is for buy tax, 2 is for sell tax, multiplied by denominator/// @custom:return `list[].penalty[3]` Index 0 is for tx penalty, 1 is for buy penalty, 2 is for sell penalty, multiplied by denominatorfunctionlistTaxBeneficiaries() externalviewreturns (taxBeneficiaryView[] memory list) {
list =new taxBeneficiaryView[](6);
unchecked {
for (uint8 i; i <6; i++) { list[i] = taxBeneficiaryView(_taxBeneficiary[i].account, _taxBeneficiary[i].percent, _taxBeneficiary[i].penalty, _taxBeneficiary[i].unclaimed); }
}
}
/// @notice Sets a tax beneficiary/// @dev Maximum of 5 wallets can be assigned/// @dev Slot 0 is reserved for ChainFactory revenue/// @param slot Slot number (1 to 5)/// @param account Beneficiary address/// @param percent[3] Index 0 is for tx tax, 1 is for buy tax, 2 is for sell tax, multiplied by denominator/// @param penalty[3] Index 0 is for tx penalty, 1 is for buy penalty, 2 is for sell penalty, multiplied by denominatorfunctionsetTaxBeneficiary(uint8 slot, address account, uint24[3] memory percent, uint24[3] memory penalty) externalonlyOwner{
require(!_renounced.Taxable);
require(slot >=1&& slot <=5, "Reserved");
_setTaxBeneficiary(slot, account, percent, penalty);
}
function_setTaxBeneficiary(uint8 slot, address account, uint24[3] memory percent, uint24[3] memory penalty) internal{
require(slot <=5);
require(account !=address(this) && account !=address(0));
taxBeneficiary storage taxBeneficiarySlot = _taxBeneficiary[slot];
if (slot >0&& account ==address(0xdEaD) && taxBeneficiarySlot.unclaimed >0) { revert("Unclaimed taxes"); }
unchecked {
_totalTxTax += percent[0] - taxBeneficiarySlot.percent[0];
_totalBuyTax += percent[1] - taxBeneficiarySlot.percent[1];
_totalSellTax += percent[2] - taxBeneficiarySlot.percent[2];
_totalPenaltyTxTax += penalty[0] - taxBeneficiarySlot.penalty[0];
_totalPenaltyBuyTax += penalty[1] - taxBeneficiarySlot.penalty[1];
_totalPenaltySellTax += penalty[2] - taxBeneficiarySlot.penalty[2];
require(_totalTxTax <=25* _denominator && ((_totalBuyTax <=25* _denominator && _totalSellTax <=25* _denominator) && (_totalBuyTax + _totalSellTax <=25* _denominator)), "High Tax");
require(_totalPenaltyTxTax <=90* _denominator && _totalPenaltyBuyTax <=90* _denominator && _totalPenaltySellTax <=90* _denominator, "Invalid Penalty");
taxBeneficiarySlot.account = account;
taxBeneficiarySlot.percent = percent;
if (_initialized && slot >0) { _setTaxBeneficiary(0, _taxBeneficiary[0].account, [ uint24(0), uint24(0), uint24(0) ], [ _taxBeneficiary[0].penalty[0] +uint24((penalty[0] *10/100) - (taxBeneficiarySlot.penalty[0] *10/100)), _taxBeneficiary[0].penalty[1] +uint24((penalty[1] *10/100) - (taxBeneficiarySlot.penalty[1] *10/100)), _taxBeneficiary[0].penalty[2] +uint24((penalty[2] *10/100) - (taxBeneficiarySlot.penalty[2] *10/100)) ]); }
taxBeneficiarySlot.penalty = penalty;
}
if (!taxBeneficiarySlot.exists) { taxBeneficiarySlot.exists =true; }
emit SetTaxBeneficiary(slot, account, percent, penalty);
}
/// @notice Triggers the tax distribution/// @dev Will only be executed if there is no ongoing swap or tax distributionfunctionautoTaxDistribute() external{
require(msg.sender== _owner || _whitelisted[msg.sender], "Unauthorized");
require(!_swapping &&!_distributing);
_autoTaxDistribute();
}
function_autoTaxDistribute() internallockDistributing{
if (_totalTaxUnclaimed ==0) { return; }
unchecked {
uint256 distributedTaxes;
for (uint8 i; i <6; i++) {
taxBeneficiary storage taxBeneficiarySlot = _taxBeneficiary[i];
address account = taxBeneficiarySlot.account;
if (taxBeneficiarySlot.unclaimed ==0|| account ==address(0xdEaD) || account == _dex.pair) { continue; }
uint256 unclaimed = _percentage(address(_taxToken) ==address(this) ? _amountForTaxDistribution : _amountSwappedForTaxDistribution, (100*uint256(_denominator) * taxBeneficiarySlot.unclaimed) / _totalTaxUnclaimed);
uint256 _distributedTaxes = _distribute(account, unclaimed);
if (_distributedTaxes >0) {
taxBeneficiarySlot.unclaimed -= _distributedTaxes;
distributedTaxes += _distributedTaxes;
}
}
_lastTaxDistribution = _timestamp();
if (distributedTaxes >0) {
_totalTaxUnclaimed -= distributedTaxes;
emit TaxDistributed(distributedTaxes);
}
}
}
function_distribute(address account, uint256 unclaimed) privatereturns (uint256) {
if (unclaimed ==0) { return0; }
unchecked {
if (address(_taxToken) ==address(this)) {
if (_balance[account] + unclaimed > _maxBalanceAmount &&!_whitelisted[account]) {
unclaimed = _maxBalanceAmount > _balance[account] ? _maxBalanceAmount - _balance[account] : 0;
if (unclaimed ==0) { return0; }
}
super._transfer(address(this), account, unclaimed);
_amountForTaxDistribution -= unclaimed;
} else {
uint256 percent = (100*uint256(_denominator) * unclaimed) / _amountSwappedForTaxDistribution;
uint256 amount;
if (address(_taxToken) == _dex.WETH) {
amount = _percentage(_ethForTaxDistribution, percent);
(bool success, ) =payable(account).call{ value: amount, gas: 30000 }("");
if (!success) { return0; }
_ethForTaxDistribution -= amount;
} else {
amount = _percentage(_tokensForTaxDistribution[address(_taxToken)], percent);
try _taxToken.transfer(account, amount) { _tokensForTaxDistribution[address(_taxToken)] -= amount; } catch { return0; }
}
_amountSwappedForTaxDistribution -= unclaimed;
}
}
return unclaimed;
}
/// @notice Suspend or reinstate tax collection/// @dev Also applies to early penalties/// @param status True to suspend, False to reinstate existent taxesfunctionsuspendTaxes(bool status) externalonlyOwner{
require(!_renounced.Taxable);
_suspendTaxes = status;
}
/// @notice Checks if tax collection is currently suspendedfunctiontaxesSuspended() externalviewreturns (bool) {
return _suspendTaxes;
}
/// @notice Removes the penalty status of a wallet/// @param account Address to depenalizefunctionremovePenalty(address account) externalonlyOwner{
require(!_renounced.Taxable);
_holder[account].penalty =false;
}
/// @notice Check if a wallet is penalized due to an early transaction/// @param account Address to checkfunctionisPenalized(address account) externalviewreturns (bool) {
return _holder[account].penalty;
}
/// @notice Returns the period of time during which early buyers will be penalized from the time trading was enabledfunctiongetEarlyPenaltyTime() externalviewreturns (uint32) {
return _earlyPenaltyTime;
}
/// @notice Defines the period of time during which early buyers will be penalized from the time trading was enabled/// @dev Must be less or equal to 1 hour/// @param time Time, in secondsfunctionsetEarlyPenaltyTime(uint32 time) externalonlyOwner{
require(!_renounced.Taxable);
require(time <=600);
_setEarlyPenaltyTime(time);
}
function_setEarlyPenaltyTime(uint32 time) internal{
_earlyPenaltyTime = time;
emit SetEarlyPenaltyTime(time);
}
}
Contract Source Code
File 10 of 13: CF_Whitelist.sol
// SPDX-License-Identifier: MITpragmasolidity 0.8.25;import"./CF_Common.sol";
import"./CF_Ownable.sol";
abstractcontractCF_WhitelistisCF_Common, CF_Ownable{
eventWhitelisted(addressindexed account, bool status);
eventRenouncedWhitelist();
/// @notice Permanently renounce and prevent the owner from being able to update the whitelist/// @dev Existing entries will continue to be effectivefunctionrenounceWhitelist() externalonlyOwner{
_renounced.Whitelist =true;
emit RenouncedWhitelist();
}
/// @notice Check if an address is whitelisted/// @param account Address to checkfunctionisWhitelisted(address account) externalviewreturns (bool) {
return _whitelisted[account];
}
/// @notice Add or remove an address from the whitelist/// @param status True for adding, False for removingfunctionwhitelist(address account, bool status) publiconlyOwner{
_whitelist(account, status);
}
function_whitelist(address account, bool status) internal{
require(!_renounced.Whitelist);
require(account !=address(0) && account !=address(0xdEaD));
require(account != _dex.router && account != _dex.pair, "DEX router and pair are privileged");
_whitelisted[account] = status;
emit Whitelisted(account, status);
}
/// @notice Add or remove multiple addresses from the whitelist/// @param status True for adding, False for removingfunctionwhitelist(address[] calldata accounts, bool status) externalonlyOwner{
unchecked {
uint256 cnt = accounts.length;
for (uint256 i; i < cnt; i++) { _whitelist(accounts[i], status); }
}
}
function_initialWhitelist(address[5] memory accounts) internal{
require(!_initialized);
unchecked {
for (uint256 i; i <5; i++) { _whitelist(accounts[i], true); }
}
}
}