编译器
0.8.23+commit.f704f362
文件 1 的 22:AccessControl.sol
pragma solidity ^0.8.0;
import "./IAccessControl.sol";
import "../utils/Context.sol";
import "../utils/Strings.sol";
import "../utils/introspection/ERC165.sol";
abstract contract AccessControl is Context, IAccessControl, ERC165 {
struct RoleData {
mapping(address => bool) members;
bytes32 adminRole;
}
mapping(bytes32 => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
modifier onlyRole(bytes32 role) {
_checkRole(role);
_;
}
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
}
function hasRole(bytes32 role, address account) public view virtual override returns (bool) {
return _roles[role].members[account];
}
function _checkRole(bytes32 role) internal view virtual {
_checkRole(role, _msgSender());
}
function _checkRole(bytes32 role, address account) internal view virtual {
if (!hasRole(role, account)) {
revert(
string(
abi.encodePacked(
"AccessControl: account ",
Strings.toHexString(account),
" is missing role ",
Strings.toHexString(uint256(role), 32)
)
)
);
}
}
function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {
return _roles[role].adminRole;
}
function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_grantRole(role, account);
}
function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_revokeRole(role, account);
}
function renounceRole(bytes32 role, address account) public virtual override {
require(account == _msgSender(), "AccessControl: can only renounce roles for self");
_revokeRole(role, account);
}
function _setupRole(bytes32 role, address account) internal virtual {
_grantRole(role, account);
}
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
bytes32 previousAdminRole = getRoleAdmin(role);
_roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
function _grantRole(bytes32 role, address account) internal virtual {
if (!hasRole(role, account)) {
_roles[role].members[account] = true;
emit RoleGranted(role, account, _msgSender());
}
}
function _revokeRole(bytes32 role, address account) internal virtual {
if (hasRole(role, account)) {
_roles[role].members[account] = false;
emit RoleRevoked(role, account, _msgSender());
}
}
}
文件 2 的 22:Address.sol
pragma solidity ^0.8.1;
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);
}
}
}
文件 3 的 22:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
文件 4 的 22:ERC165.sol
pragma solidity ^0.8.0;
import "./IERC165.sol";
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
文件 5 的 22:ERC20.sol
pragma solidity ^0.8.0;
import "./IERC20.sol";
import "./extensions/IERC20Metadata.sol";
import "../../utils/Context.sol";
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 {}
}
文件 6 的 22:EnumerableSet.sol
pragma solidity ^0.8.0;
library EnumerableSet {
struct Set {
bytes32[] _values;
mapping(bytes32 => uint256) _indexes;
}
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
set._indexes[value] = set._values.length;
return true;
} else {
return false;
}
}
function _remove(Set storage set, bytes32 value) private returns (bool) {
uint256 valueIndex = set._indexes[value];
if (valueIndex != 0) {
uint256 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
if (lastIndex != toDeleteIndex) {
bytes32 lastValue = set._values[lastIndex];
set._values[toDeleteIndex] = lastValue;
set._indexes[lastValue] = valueIndex;
}
set._values.pop();
delete set._indexes[value];
return true;
} else {
return false;
}
}
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._indexes[value] != 0;
}
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
function _at(Set storage set, uint256 index) private view returns (bytes32) {
return set._values[index];
}
function _values(Set storage set) private view returns (bytes32[] memory) {
return set._values;
}
struct Bytes32Set {
Set _inner;
}
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
bytes32[] memory store = _values(set._inner);
bytes32[] memory result;
assembly {
result := store
}
return result;
}
struct AddressSet {
Set _inner;
}
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
function values(AddressSet storage set) internal view returns (address[] memory) {
bytes32[] memory store = _values(set._inner);
address[] memory result;
assembly {
result := store
}
return result;
}
struct UintSet {
Set _inner;
}
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
function values(UintSet storage set) internal view returns (uint256[] memory) {
bytes32[] memory store = _values(set._inner);
uint256[] memory result;
assembly {
result := store
}
return result;
}
}
文件 7 的 22:IAccessControl.sol
pragma solidity ^0.8.0;
interface IAccessControl {
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
function hasRole(bytes32 role, address account) external view returns (bool);
function getRoleAdmin(bytes32 role) external view returns (bytes32);
function grantRole(bytes32 role, address account) external;
function revokeRole(bytes32 role, address account) external;
function renounceRole(bytes32 role, address account) external;
}
文件 8 的 22:IBuyBackHandler.sol
pragma solidity 0.8.23;
import { ITokenLauncherLiquidityPoolFactory } from "./ITokenLauncherLiquidityPoolFactory.sol";
interface IBuyBackHandler {
function BUYBACK_CALLER_ROLE() external view returns (bytes32);
function buyback(address treasury, ITokenLauncherLiquidityPoolFactory.BuyBackDetails memory buybackDetails) external;
function grantRole(bytes32 role, address account) external;
}
文件 9 的 22:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 10 的 22:IERC20.sol
pragma solidity ^0.8.0;
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);
}
文件 11 的 22:IERC20Metadata.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
interface IERC20Metadata is IERC20 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
}
文件 12 的 22:IERC20Permit.sol
pragma solidity ^0.8.0;
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);
}
文件 13 的 22:ITokenLauncherCommon.sol
pragma solidity 0.8.23;
interface ITokenLauncherCommon {
enum TokenType {
ERC20,
ERC721,
ERC1155
}
enum PaymentMethod {
NATIVE,
USD,
FLOKI
}
}
文件 14 的 22:ITokenLauncherERC20.sol
pragma solidity 0.8.23;
import { ITokenLauncherCommon } from "./ITokenLauncherCommon.sol";
interface ITokenLauncherERC20 is ITokenLauncherCommon {
struct FeeDetails {
uint256 percentage;
bool onlyOnSwaps;
}
struct Fees {
FeeDetails transferFee;
FeeDetails burn;
FeeDetails reflection;
FeeDetails buyback;
}
struct CreateErc20Input {
string name;
string symbol;
string logo;
uint8 decimals;
uint256 initialSupply;
uint256 maxSupply;
address treasury;
address owner;
address referrer;
address tokenStore;
Fees fees;
address buybackHandler;
PaymentMethod paymentMethod;
}
function tokenLauncherStore() external returns (address);
function liquidityPoolFactory() external returns (address);
function buybackHandler() external returns (address);
function createErc20(CreateErc20Input memory input) external payable;
}
文件 15 的 22:ITokenLauncherLiquidityPoolFactory.sol
pragma solidity 0.8.23;
interface ITokenLauncherLiquidityPoolFactory {
struct LiquidityPoolDetails {
address sourceToken;
address pairedToken;
uint256 amountSourceToken;
uint256 amountPairedToken;
address routerAddress;
}
struct LockLPDetails {
uint256 lockLPTokenPercentage;
uint256 unlockTimestamp;
address beneficiary;
bool isVesting;
}
struct BuyBackDetails {
address pairToken;
address router;
uint256 liquidityBasisPoints;
uint256 priceImpactBasisPoints;
}
struct CreateV2Input {
address owner;
address treasury;
LiquidityPoolDetails liquidityPoolDetails;
LockLPDetails lockLPDetails;
BuyBackDetails buybackDetails;
}
struct CreateV2Output {
address liquidityPoolToken;
uint256 liquidity;
}
function createV2LiquidityPool(CreateV2Input memory input) external payable returns (CreateV2Output memory);
}
文件 16 的 22:IUniswapV2Router01.sol
pragma solidity >=0.6.2;
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);
}
文件 17 的 22:IUniswapV2Router02.sol
pragma solidity >=0.6.2;
import './IUniswapV2Router01.sol';
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;
}
文件 18 的 22:Math.sol
pragma solidity ^0.8.0;
library Math {
enum Rounding {
Down,
Up,
Zero
}
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
function average(uint256 a, uint256 b) internal pure returns (uint256) {
return (a & b) + (a ^ b) / 2;
}
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
return a == 0 ? 0 : (a - 1) / b + 1;
}
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
uint256 prod0;
uint256 prod1;
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
if (prod1 == 0) {
return prod0 / denominator;
}
require(denominator > prod1, "Math: mulDiv overflow");
uint256 remainder;
assembly {
remainder := mulmod(x, y, denominator)
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
uint256 twos = denominator & (~denominator + 1);
assembly {
denominator := div(denominator, twos)
prod0 := div(prod0, twos)
twos := add(div(sub(0, twos), twos), 1)
}
prod0 |= prod1 * twos;
uint256 inverse = (3 * denominator) ^ 2;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
result = prod0 * inverse;
return result;
}
}
function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 result = 1 << (log2(a) >> 1);
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10 ** 64) {
value /= 10 ** 64;
result += 64;
}
if (value >= 10 ** 32) {
value /= 10 ** 32;
result += 32;
}
if (value >= 10 ** 16) {
value /= 10 ** 16;
result += 16;
}
if (value >= 10 ** 8) {
value /= 10 ** 8;
result += 8;
}
if (value >= 10 ** 4) {
value /= 10 ** 4;
result += 4;
}
if (value >= 10 ** 2) {
value /= 10 ** 2;
result += 2;
}
if (value >= 10 ** 1) {
result += 1;
}
}
return result;
}
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
}
}
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
}
}
}
文件 19 的 22:SafeERC20.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/IERC20Permit.sol";
import "../../../utils/Address.sol";
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));
}
}
文件 20 的 22:SignedMath.sol
pragma solidity ^0.8.0;
library SignedMath {
function max(int256 a, int256 b) internal pure returns (int256) {
return a > b ? a : b;
}
function min(int256 a, int256 b) internal pure returns (int256) {
return a < b ? a : b;
}
function average(int256 a, int256 b) internal pure returns (int256) {
int256 x = (a & b) + ((a ^ b) >> 1);
return x + (int256(uint256(x) >> 255) & (a ^ b));
}
function abs(int256 n) internal pure returns (uint256) {
unchecked {
return uint256(n >= 0 ? n : -n);
}
}
}
文件 21 的 22:Strings.sol
pragma solidity ^0.8.0;
import "./math/Math.sol";
import "./math/SignedMath.sol";
library Strings {
bytes16 private constant _SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = Math.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
assembly {
mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
function toString(int256 value) internal pure returns (string memory) {
return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value))));
}
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, Math.log256(value) + 1);
}
}
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
function equal(string memory a, string memory b) internal pure returns (bool) {
return keccak256(bytes(a)) == keccak256(bytes(b));
}
}
文件 22 的 22:TokenFiERC20.sol
pragma solidity 0.8.23;
import { AccessControl } from "@openzeppelin/contracts/access/AccessControl.sol";
import { ERC20, IERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import { IUniswapV2Router02 } from "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol";
import { ITokenLauncherERC20 } from "../interfaces/ITokenLauncherERC20.sol";
import { ITokenLauncherLiquidityPoolFactory } from "../interfaces/ITokenLauncherLiquidityPoolFactory.sol";
import { IBuyBackHandler } from "../interfaces/IBuyBackHandler.sol";
contract TokenFiERC20 is ERC20, AccessControl {
using EnumerableSet for EnumerableSet.AddressSet;
using SafeERC20 for IERC20;
bytes32 public constant FEE_MANAGER_ROLE = keccak256("FEE_MANAGER_ROLE");
address public treasury;
uint256 public maxSupply;
string public logo;
ITokenLauncherERC20.Fees public fees;
ITokenLauncherLiquidityPoolFactory.BuyBackDetails public buybackDetails;
address public buybackHandler;
address public tokenLauncher;
bool public isReflectionToken;
uint8 private _decimals;
address public constant BURN_ADDRESS = 0x000000000000000000000000000000000000dEaD;
uint256 public constant MULTIPLIER_BASIS = 1e4;
EnumerableSet.AddressSet private _exemptedFromTax;
EnumerableSet.AddressSet internal _exchangePools;
uint256 public constant MAX = type(uint256).max / 2;
mapping(address => uint256) private _rOwned;
mapping(address => uint256) private _tOwned;
mapping(address => bool) private _isExcludedFromReflectionRewards;
address[] private _excluded;
struct TotalReflection {
uint256 t;
uint256 r;
uint256 tFee;
}
TotalReflection public totalReflection;
event ExemptedAdded(address indexed account);
event ExemptedRemoved(address indexed account);
event ExchangePoolAdded(address indexed pool);
event ExchangePoolRemoved(address indexed pool);
event TokenLauncherUpdated(address indexed newTokenLauncher);
event TransferTax(address indexed account, address indexed receiver, uint256 amount, string indexed taxType);
event BuyBackDetailsUpdated(address indexed router, address indexed pairToken, uint256 liquidityBasisPoints, uint256 priceImpactBasisPoints);
constructor(ITokenLauncherERC20.CreateErc20Input memory _input) ERC20(_input.name, _input.symbol) {
require(_input.owner != address(0), "TokenFiERC20: owner cannot be Address Zero ");
require(_input.maxSupply >= _input.initialSupply, "TokenFiERC20: initialSupply cannot be greater than maxSupply");
treasury = _input.treasury;
maxSupply = _input.maxSupply;
logo = _input.logo;
_decimals = _input.decimals;
uint256 maxFee = _input.fees.transferFee.percentage + _input.fees.burn.percentage + _input.fees.reflection.percentage + _input.fees.buyback.percentage;
require(maxFee <= MULTIPLIER_BASIS, "TokenFiERC20: fees sum must be less than 100%");
fees = _input.fees;
buybackHandler = _input.buybackHandler;
if (_input.fees.reflection.percentage > 0) {
require(_input.initialSupply > 0, "TokenFiERC20.constructor: initialSupply must be greater than 0");
totalReflection.r = (MAX - (MAX % _input.initialSupply));
_rOwned[_input.treasury] = totalReflection.r;
totalReflection.t = _input.initialSupply;
_tOwned[_input.treasury] = _input.initialSupply;
isReflectionToken = true;
emit Transfer(address(0), _input.treasury, _input.initialSupply);
} else {
_mint(_input.treasury, _input.initialSupply);
}
_exemptedFromTax.add(_input.buybackHandler);
tokenLauncher = msg.sender;
_grantRole(DEFAULT_ADMIN_ROLE, _input.owner);
_grantRole(FEE_MANAGER_ROLE, tokenLauncher);
_grantRole(DEFAULT_ADMIN_ROLE, _input.tokenStore);
}
function decimals() public view override returns (uint8) {
return _decimals;
}
function setBuybackDetails(ITokenLauncherLiquidityPoolFactory.BuyBackDetails memory _buybackDetails) external onlyRole(FEE_MANAGER_ROLE) {
if (fees.buyback.percentage > 0) {
require(_buybackDetails.liquidityBasisPoints <= MULTIPLIER_BASIS, "TokenFiERC20: liquidityBasisPoints must be less than 10,000");
require(_buybackDetails.priceImpactBasisPoints <= MULTIPLIER_BASIS, "TokenFiERC20: priceImpactBasisPoints must be less than 10,000");
require(_buybackDetails.router != address(0), "TokenFiERC20: router cannot be empty");
require(_buybackDetails.pairToken != address(0), "TokenFiERC20: pairToken cannot be empty");
}
buybackDetails = _buybackDetails;
emit BuyBackDetailsUpdated(
_buybackDetails.router,
_buybackDetails.pairToken,
_buybackDetails.liquidityBasisPoints,
_buybackDetails.priceImpactBasisPoints
);
}
function addExchangePool(address pool) external onlyRole(FEE_MANAGER_ROLE) {
require(pool != address(0), "TokenFiERC20: address cannot be empty");
_exchangePools.add(pool);
emit ExchangePoolAdded(pool);
}
function addExemptAddress(address account) external onlyRole(FEE_MANAGER_ROLE) {
_exemptedFromTax.add(account);
emit ExemptedAdded(account);
}
function updateFees(ITokenLauncherERC20.Fees memory _fees) external onlyRole(DEFAULT_ADMIN_ROLE) {
if (isReflectionToken) {
require(_fees.reflection.percentage > 0, "TokenFiERC20: reflection percentage must be non-zero");
} else {
require(_fees.reflection.percentage == 0, "TokenFiERC20: reflection percentage must be zero");
}
uint256 maxFee = _fees.transferFee.percentage + _fees.burn.percentage + _fees.reflection.percentage + _fees.buyback.percentage;
require(maxFee <= MULTIPLIER_BASIS, "TokenFiERC20: fees sum must be less than 100%");
fees = _fees;
}
function isExemptedFromTax(address account) external view returns (bool) {
return _exemptedFromTax.contains(account);
}
function isExchangePool(address pool) external view returns (bool) {
return _exchangePools.contains(pool);
}
function balanceOf(address account) public view override returns (uint256) {
if (isReflectionToken) {
return _balanceOfReflection(account);
}
return super.balanceOf(account);
}
function totalSupply() public view override returns (uint256) {
if (isReflectionToken) {
return totalReflection.t;
}
return super.totalSupply();
}
function isExcludedFromReflectionRewards(address account) public view returns (bool) {
return _isExcludedFromReflectionRewards[account] || account == address(this);
}
function reflect(uint256 tAmount) external onlyReflection {
address sender = _msgSender();
require(!isExcludedFromReflectionRewards(sender), "Excluded addresses cannot call this function");
(uint256 rAmount, , , , ) = _getValues(tAmount, tAmount, false, true);
_rOwned[sender] = _rOwned[sender] - rAmount;
totalReflection.r = totalReflection.r - rAmount;
totalReflection.tFee = totalReflection.tFee + tAmount;
}
function reflectionFromToken(uint256 tAmount, bool deductTransferFee) public view returns (uint256) {
require(tAmount <= totalReflection.t, "Amount must be less than supply");
if (!deductTransferFee) {
(uint256 rAmount, , , , ) = _getValues(tAmount, tAmount, false, true);
return rAmount;
} else {
(, uint256 rTransferAmount, , , ) = _getValues(tAmount, tAmount, false, true);
return rTransferAmount;
}
}
function tokenFromReflection(uint256 rAmount) public view returns (uint256) {
require(rAmount <= totalReflection.r, "Amount must be less than total reflections");
uint256 currentRate = _getRate();
return rAmount / currentRate;
}
function excludeAccount(address account) external onlyReflection onlyFromAdminOrLauncher {
require(!isExcludedFromReflectionRewards(account), "Account is already excluded");
if (_rOwned[account] > 0) {
_tOwned[account] = tokenFromReflection(_rOwned[account]);
}
_isExcludedFromReflectionRewards[account] = true;
_excluded.push(account);
}
function includeAccount(address account) external onlyReflection onlyFromAdminOrLauncher {
require(isExcludedFromReflectionRewards(account), "Account is already included");
for (uint256 i = 0; i < _excluded.length; i++) {
if (_excluded[i] == account) {
uint256 currentRate = _getRate();
totalReflection.r = totalReflection.r - _rOwned[account];
_rOwned[account] = _tOwned[account] * currentRate;
_tOwned[account] = 0;
totalReflection.r = totalReflection.r + _rOwned[account];
_isExcludedFromReflectionRewards[account] = false;
_excluded[i] = _excluded[_excluded.length - 1];
_excluded.pop();
break;
}
}
}
function totalFees() public view returns (uint256) {
return totalReflection.tFee;
}
function _balanceOfReflection(address account) private view returns (uint256) {
if (isExcludedFromReflectionRewards(account)) return _tOwned[account];
return tokenFromReflection(_rOwned[account]);
}
function _transferStandard(
address sender,
address recipient,
uint256 tAmount,
uint256 tTransferAmount,
uint256 rAmount,
uint256 rTransferAmount,
bool shouldReflectFee
) private {
_rOwned[sender] = _rOwned[sender] - rAmount;
if (shouldReflectFee) {
_rOwned[recipient] = _rOwned[recipient] + rTransferAmount;
} else {
_rOwned[recipient] = _rOwned[recipient] + rAmount;
}
}
function _transferToExcluded(
address sender,
address recipient,
uint256 tAmount,
uint256 tTransferAmount,
uint256 rAmount,
uint256 rTransferAmount,
bool shouldReflectFee
) private {
_rOwned[sender] = _rOwned[sender] - rAmount;
if (shouldReflectFee) {
_tOwned[recipient] = _tOwned[recipient] + tTransferAmount;
_rOwned[recipient] = _rOwned[recipient] + rTransferAmount;
} else {
_tOwned[recipient] = _tOwned[recipient] + tAmount;
_rOwned[recipient] = _rOwned[recipient] + rAmount;
}
}
function _transferFromExcluded(
address sender,
address recipient,
uint256 tAmount,
uint256 tTransferAmount,
uint256 rAmount,
uint256 rTransferAmount,
bool shouldReflectFee
) private {
_tOwned[sender] = _tOwned[sender] - tAmount;
_rOwned[sender] = _rOwned[sender] - rAmount;
if (shouldReflectFee) {
_rOwned[recipient] = _rOwned[recipient] + rTransferAmount;
} else {
_rOwned[recipient] = _rOwned[recipient] + rAmount;
}
}
function _transferBothExcluded(
address sender,
address recipient,
uint256 tAmount,
uint256 tTransferAmount,
uint256 rAmount,
uint256 rTransferAmount,
bool shouldReflectFee
) private {
_tOwned[sender] = _tOwned[sender] - tAmount;
_rOwned[sender] = _rOwned[sender] - rAmount;
if (shouldReflectFee) {
_tOwned[recipient] = _tOwned[recipient] + tTransferAmount;
_rOwned[recipient] = _rOwned[recipient] + rTransferAmount;
} else {
_tOwned[recipient] = _tOwned[recipient] + tAmount;
_rOwned[recipient] = _rOwned[recipient] + rAmount;
}
}
function _reflectFee(uint256 rFee, uint256 tFee) private {
totalReflection.r = totalReflection.r - rFee;
totalReflection.tFee = totalReflection.tFee + tFee;
}
function _getValues(
uint256 tAmount,
uint256 tAmountOriginal,
bool isSwap,
bool shouldReflectFee
) private view returns (uint256, uint256, uint256, uint256, uint256) {
(uint256 tTransferAmount, uint256 tFee) = _getTValues(tAmount, tAmountOriginal, isSwap, shouldReflectFee);
uint256 currentRate = _getRate();
(uint256 rAmount, uint256 rTransferAmount, uint256 rFee) = _getRValues(tAmount, tFee, currentRate);
return (rAmount, rTransferAmount, rFee, tTransferAmount, tFee);
}
function _getTValues(uint256 tAmount, uint256 tAmountOriginal, bool isSwap, bool shouldReflectFee) private view returns (uint256, uint256) {
bool shouldReflect = (!fees.reflection.onlyOnSwaps || isSwap);
if (!shouldReflect || !shouldReflectFee) return (tAmount, 0);
uint256 tFee = (tAmountOriginal * fees.reflection.percentage) / MULTIPLIER_BASIS;
uint256 tTransferAmount = tAmount - tFee;
return (tTransferAmount, tFee);
}
function _getRValues(uint256 tAmount, uint256 tFee, uint256 currentRate) private pure returns (uint256, uint256, uint256) {
uint256 rAmount = tAmount * currentRate;
uint256 rFee = tFee * currentRate;
uint256 rTransferAmount = rAmount - rFee;
return (rAmount, rTransferAmount, rFee);
}
function _getRate() private view returns (uint256) {
(uint256 rSupply, uint256 tSupply) = _getCurrentSupply();
return rSupply / tSupply;
}
function _getCurrentSupply() private view returns (uint256, uint256) {
uint256 rSupply = totalReflection.r;
uint256 tSupply = totalReflection.t;
for (uint256 i = 0; i < _excluded.length; i++) {
if (_rOwned[_excluded[i]] > rSupply || _tOwned[_excluded[i]] > tSupply) return (totalReflection.r, totalReflection.t);
rSupply = rSupply - _rOwned[_excluded[i]];
tSupply = tSupply - _tOwned[_excluded[i]];
}
if (rSupply < totalReflection.r / totalReflection.t) return (totalReflection.r, totalReflection.t);
return (rSupply, tSupply);
}
function removeExchangePool(address pool) external onlyRole(FEE_MANAGER_ROLE) {
_exchangePools.remove(pool);
emit ExchangePoolRemoved(pool);
}
function removeExemptAddress(address account) external onlyRole(FEE_MANAGER_ROLE) {
_exemptedFromTax.remove(account);
emit ExemptedRemoved(account);
}
function _transfer(address sender, address recipient, uint256 amount) internal virtual override {
bool isSwap = _isSwap(sender, recipient);
bool exemptedFromTax = _isExemptedFromTax(sender, recipient);
uint256 originalAmount = amount;
if (fees.transferFee.percentage > 0 && (!fees.transferFee.onlyOnSwaps || isSwap) && !exemptedFromTax) {
uint256 transferFee = (originalAmount * fees.transferFee.percentage) / MULTIPLIER_BASIS;
_transferInternal(sender, treasury, transferFee, originalAmount, false);
amount -= transferFee;
emit TransferTax(sender, treasury, transferFee, "transferFee");
}
if (fees.burn.percentage > 0 && (!fees.burn.onlyOnSwaps || isSwap) && !exemptedFromTax) {
uint256 burnFee = (originalAmount * fees.burn.percentage) / MULTIPLIER_BASIS;
_transferInternal(sender, BURN_ADDRESS, burnFee, originalAmount, false);
amount -= burnFee;
emit TransferTax(sender, BURN_ADDRESS, burnFee, "burnFee");
}
if (fees.buyback.percentage > 0 && (!fees.buyback.onlyOnSwaps || isSwap) && !exemptedFromTax) {
uint256 buybackFee = (originalAmount * fees.buyback.percentage) / MULTIPLIER_BASIS;
_transferInternal(sender, buybackHandler, buybackFee, originalAmount, false);
if (!_exchangePools.contains(sender) && buybackDetails.router != address(0)) {
IBuyBackHandler(buybackHandler).buyback(treasury, buybackDetails);
}
amount -= buybackFee;
emit TransferTax(sender, buybackHandler, buybackFee, "buybackFee");
}
_transferInternal(sender, recipient, amount, originalAmount, true);
}
function _transferReflection(address sender, address recipient, uint256 tAmount, uint256 tAmountOriginal, bool shouldReflectFee) private {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
require(tAmount > 0, "Transfer amount must be greater than zero");
bool isSwap = _isSwap(sender, recipient);
address liquidityPoolFactory = ITokenLauncherERC20(tokenLauncher).liquidityPoolFactory();
if (sender == liquidityPoolFactory || recipient == liquidityPoolFactory) {
shouldReflectFee = false;
}
(uint256 rAmount, uint256 rTransferAmount, uint256 rFee, uint256 tTransferAmount, uint256 tFee) = _getValues(
tAmount,
tAmountOriginal,
isSwap,
shouldReflectFee
);
if (isExcludedFromReflectionRewards(sender) && !isExcludedFromReflectionRewards(recipient)) {
_transferFromExcluded(sender, recipient, tAmount, tTransferAmount, rAmount, rTransferAmount, shouldReflectFee);
} else if (!isExcludedFromReflectionRewards(sender) && isExcludedFromReflectionRewards(recipient)) {
_transferToExcluded(sender, recipient, tAmount, tTransferAmount, rAmount, rTransferAmount, shouldReflectFee);
} else if (!isExcludedFromReflectionRewards(sender) && !isExcludedFromReflectionRewards(recipient)) {
_transferStandard(sender, recipient, tAmount, tTransferAmount, rAmount, rTransferAmount, shouldReflectFee);
} else if (isExcludedFromReflectionRewards(sender) && isExcludedFromReflectionRewards(recipient)) {
_transferBothExcluded(sender, recipient, tAmount, tTransferAmount, rAmount, rTransferAmount, shouldReflectFee);
}
emit Transfer(sender, recipient, tTransferAmount);
if (shouldReflectFee) {
_reflectFee(rFee, tFee);
emit TransferTax(sender, address(0), tFee, "reflectionFee");
}
}
function _transferInternal(address sender, address recipient, uint256 amount, uint256 originalAmount, bool shouldReflectFee) private {
if (isReflectionToken) {
_transferReflection(sender, recipient, amount, originalAmount, shouldReflectFee);
} else {
super._transfer(sender, recipient, amount);
}
}
function _isSwap(address sender, address recipient) internal view returns (bool) {
return _exchangePools.contains(sender) || _exchangePools.contains(recipient);
}
function _isExemptedFromTax(address sender, address recipient) internal view returns (bool) {
return _exemptedFromTax.contains(sender) || _exemptedFromTax.contains(recipient);
}
function _mintReflection(address account, uint256 amount) private {
uint256 _rAmount = amount * _getRate();
totalReflection.t = totalReflection.t + amount;
totalReflection.r = totalReflection.r + _rAmount;
if (isExcludedFromReflectionRewards(account)) {
_tOwned[account] = _tOwned[account] + amount;
}
_rOwned[account] = _rOwned[account] + _rAmount;
emit Transfer(address(0), account, amount);
}
function mint(address to, uint256 amount) external onlyRole(DEFAULT_ADMIN_ROLE) {
require(totalSupply() + amount <= maxSupply, "TokenFiERC20: max supply exceeded");
if (isReflectionToken) {
_mintReflection(to, amount);
} else {
super._mint(to, amount);
}
}
function updateTokenLauncher(address _newTokenLauncher) external onlyRole(DEFAULT_ADMIN_ROLE) {
_revokeRole(FEE_MANAGER_ROLE, tokenLauncher);
tokenLauncher = _newTokenLauncher;
_grantRole(FEE_MANAGER_ROLE, _newTokenLauncher);
emit TokenLauncherUpdated(_newTokenLauncher);
}
modifier onlyFromAdminOrLauncher() {
require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender) || msg.sender == tokenLauncher, "TokenFiERC20: must be admin");
_;
}
modifier onlyReflection() {
require(isReflectionToken, "TokenFiERC20: reflection not enabled");
_;
}
}
{
"compilationTarget": {
"contracts/token-launcher/templates/TokenFiERC20.sol": "TokenFiERC20"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "none",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 10
},
"remappings": []
}
[{"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"logo","type":"string"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint256","name":"initialSupply","type":"uint256"},{"internalType":"uint256","name":"maxSupply","type":"uint256"},{"internalType":"address","name":"treasury","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"referrer","type":"address"},{"internalType":"address","name":"tokenStore","type":"address"},{"components":[{"components":[{"internalType":"uint256","name":"percentage","type":"uint256"},{"internalType":"bool","name":"onlyOnSwaps","type":"bool"}],"internalType":"struct ITokenLauncherERC20.FeeDetails","name":"transferFee","type":"tuple"},{"components":[{"internalType":"uint256","name":"percentage","type":"uint256"},{"internalType":"bool","name":"onlyOnSwaps","type":"bool"}],"internalType":"struct ITokenLauncherERC20.FeeDetails","name":"burn","type":"tuple"},{"components":[{"internalType":"uint256","name":"percentage","type":"uint256"},{"internalType":"bool","name":"onlyOnSwaps","type":"bool"}],"internalType":"struct ITokenLauncherERC20.FeeDetails","name":"reflection","type":"tuple"},{"components":[{"internalType":"uint256","name":"percentage","type":"uint256"},{"internalType":"bool","name":"onlyOnSwaps","type":"bool"}],"internalType":"struct ITokenLauncherERC20.FeeDetails","name":"buyback","type":"tuple"}],"internalType":"struct ITokenLauncherERC20.Fees","name":"fees","type":"tuple"},{"internalType":"address","name":"buybackHandler","type":"address"},{"internalType":"enum ITokenLauncherCommon.PaymentMethod","name":"paymentMethod","type":"uint8"}],"internalType":"struct ITokenLauncherERC20.CreateErc20Input","name":"_input","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"router","type":"address"},{"indexed":true,"internalType":"address","name":"pairToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"liquidityBasisPoints","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"priceImpactBasisPoints","type":"uint256"}],"name":"BuyBackDetailsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pool","type":"address"}],"name":"ExchangePoolAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pool","type":"address"}],"name":"ExchangePoolRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"ExemptedAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"ExemptedRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newTokenLauncher","type":"address"}],"name":"TokenLauncherUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"string","name":"taxType","type":"string"}],"name":"TransferTax","type":"event"},{"inputs":[],"name":"BURN_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FEE_MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MULTIPLIER_BASIS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"}],"name":"addExchangePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addExemptAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buybackDetails","outputs":[{"internalType":"address","name":"pairToken","type":"address"},{"internalType":"address","name":"router","type":"address"},{"internalType":"uint256","name":"liquidityBasisPoints","type":"uint256"},{"internalType":"uint256","name":"priceImpactBasisPoints","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buybackHandler","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"excludeAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"fees","outputs":[{"components":[{"internalType":"uint256","name":"percentage","type":"uint256"},{"internalType":"bool","name":"onlyOnSwaps","type":"bool"}],"internalType":"struct ITokenLauncherERC20.FeeDetails","name":"transferFee","type":"tuple"},{"components":[{"internalType":"uint256","name":"percentage","type":"uint256"},{"internalType":"bool","name":"onlyOnSwaps","type":"bool"}],"internalType":"struct ITokenLauncherERC20.FeeDetails","name":"burn","type":"tuple"},{"components":[{"internalType":"uint256","name":"percentage","type":"uint256"},{"internalType":"bool","name":"onlyOnSwaps","type":"bool"}],"internalType":"struct ITokenLauncherERC20.FeeDetails","name":"reflection","type":"tuple"},{"components":[{"internalType":"uint256","name":"percentage","type":"uint256"},{"internalType":"bool","name":"onlyOnSwaps","type":"bool"}],"internalType":"struct ITokenLauncherERC20.FeeDetails","name":"buyback","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"includeAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"}],"name":"isExchangePool","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isExcludedFromReflectionRewards","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isExemptedFromTax","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isReflectionToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"logo","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tAmount","type":"uint256"}],"name":"reflect","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tAmount","type":"uint256"},{"internalType":"bool","name":"deductTransferFee","type":"bool"}],"name":"reflectionFromToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"}],"name":"removeExchangePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"removeExemptAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"pairToken","type":"address"},{"internalType":"address","name":"router","type":"address"},{"internalType":"uint256","name":"liquidityBasisPoints","type":"uint256"},{"internalType":"uint256","name":"priceImpactBasisPoints","type":"uint256"}],"internalType":"struct ITokenLauncherLiquidityPoolFactory.BuyBackDetails","name":"_buybackDetails","type":"tuple"}],"name":"setBuybackDetails","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"rAmount","type":"uint256"}],"name":"tokenFromReflection","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenLauncher","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalReflection","outputs":[{"internalType":"uint256","name":"t","type":"uint256"},{"internalType":"uint256","name":"r","type":"uint256"},{"internalType":"uint256","name":"tFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"uint256","name":"percentage","type":"uint256"},{"internalType":"bool","name":"onlyOnSwaps","type":"bool"}],"internalType":"struct ITokenLauncherERC20.FeeDetails","name":"transferFee","type":"tuple"},{"components":[{"internalType":"uint256","name":"percentage","type":"uint256"},{"internalType":"bool","name":"onlyOnSwaps","type":"bool"}],"internalType":"struct ITokenLauncherERC20.FeeDetails","name":"burn","type":"tuple"},{"components":[{"internalType":"uint256","name":"percentage","type":"uint256"},{"internalType":"bool","name":"onlyOnSwaps","type":"bool"}],"internalType":"struct ITokenLauncherERC20.FeeDetails","name":"reflection","type":"tuple"},{"components":[{"internalType":"uint256","name":"percentage","type":"uint256"},{"internalType":"bool","name":"onlyOnSwaps","type":"bool"}],"internalType":"struct ITokenLauncherERC20.FeeDetails","name":"buyback","type":"tuple"}],"internalType":"struct ITokenLauncherERC20.Fees","name":"_fees","type":"tuple"}],"name":"updateFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newTokenLauncher","type":"address"}],"name":"updateTokenLauncher","outputs":[],"stateMutability":"nonpayable","type":"function"}]