BSC链智能合约挖矿系统开发部署详细流程(代码呈现)

简介: BSC链智能合约挖矿系统开发详细流程(代码呈现)

在区块链应用中,数字钱包装载的并不是数字货币,而是密钥(私钥和公钥)。

数字钱包中包含成对的私钥和公钥,公钥用于交易转账,私钥用于签名和解密。

拥有了密钥相当于拥有相应地址上数字货币的支配权。

在开发流程中,我们通过钱包来创建随机私钥、公钥、以及一串用于交易的地址信息。这段地址信息可以用于接受他人转账的数字货币,以及把你所拥有的数字货币转账给其他人。

因此在我们开发智能合约之前,首先要先准备一个数字钱包。

使用浏览器插件钱包
在开发过程当中,最常用的是浏览器插件钱包。浏览器插件钱包配置简单,插件钱包的安装和使用都很便捷。此外,由于目前大多数区块链应用都是网页的,因此通过浏览器钱包可以轻松访问目前主流的所有 Defi 和 NFT 应用。

部署参数:
例如:
name_: (名称)
symbol_: (符号)
totalSupply_: (发行量)
rewardAddr_: 要分红的代币合约,BSC常用代币地址在下方
marketingWalletAddr_: 自己的钱包
serviceAddr_: 0x333336b1f76404693a4bd3885170A0F9a807940F
buyFeeSetting_: [4,3,2,1] (分红、流动性、市场营销、燃烧)
sellFeeSetting_: [5,4,3,2] (分红、流动性、市场营销、燃烧)
tokenBalanceForReward_: 1000000000000000000000000000 (持有多少代币参与分红。数量后要加18个0)
编译/开源参数:
COMPILER: v0.8.7+commit.e28d00a7.js
Enable optimization: 开启并使用默认值200
Other Settings: default evmVersion, MIT license
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.6;

interface IUniswapV2Pair {

event Approval(
    address indexed owner,
    address indexed spender,
    uint256 value
);
event Transfer(address indexed from, address indexed to, uint256 value);

function name() external pure returns (string memory);

function symbol() external pure returns (string memory);

function decimals() external pure returns (uint8);

function totalSupply() external view returns (uint256);

function balanceOf(address owner) external view returns (uint256);

function allowance(address owner, address spender)
external
view
returns (uint256);

function approve(address spender, uint256 value) external returns (bool);

function transfer(address to, uint256 value) external returns (bool);

function transferFrom(
    address from,
    address to,
    uint256 value
) external returns (bool);

function DOMAIN_SEPARATOR() external view returns (bytes32);

function PERMIT_TYPEHASH() external pure returns (bytes32);

function nonces(address owner) external view returns (uint256);

function permit(
    address owner,
    address spender,
    uint256 value,
    uint256 deadline,
    uint8 v,
    bytes32 r,
    bytes32 s
) external;

event Mint(address indexed sender, uint256 amount0, uint256 amount1);
event Burn(
    address indexed sender,
    uint256 amount0,
    uint256 amount1,
    address indexed to
);
event Swap(
    address indexed sender,
    uint256 amount0In,
    uint256 amount1In,
    uint256 amount0Out,
    uint256 amount1Out,
    address indexed to
);
event Sync(uint112 reserve0, uint112 reserve1);

function MINIMUM_LIQUIDITY() external pure returns (uint256);

function factory() external view returns (address);

function token0() external view returns (address);

function token1() external view returns (address);

function getReserves()
external
view
returns (
    uint112 reserve0,
    uint112 reserve1,
    uint32 blockTimestampLast
);

function price0CumulativeLast() external view returns (uint256);

function price1CumulativeLast() external view returns (uint256);

function kLast() external view returns (uint256);

function mint(address to) external returns (uint256 liquidity);

function burn(address to)
external
returns (uint256 amount0, uint256 amount1);

function swap(
    uint256 amount0Out,
    uint256 amount1Out,
    address to,
    bytes calldata data
) external;

function skim(address to) external;

function sync() external;

function initialize(address, address) external;

}

interface IUniswapV2Factory {

event PairCreated(
    address indexed token0,
    address indexed token1,
    address pair,
    uint256
);

function feeTo() external view returns (address);

function feeToSetter() external view returns (address);

function getPair(address tokenA, address tokenB)
external
view
returns (address pair);

function allPairs(uint256) external view returns (address pair);

function allPairsLength() external view returns (uint256);

function createPair(address tokenA, address tokenB)
external
returns (address pair);

function setFeeTo(address) external;

function setFeeToSetter(address) external;

}

interface IERC20 {

/**
 * @dev Returns the amount of tokens in existence.
 */
function totalSupply() external view returns (uint256);

function decimals() external view returns (uint8);

function name() external view returns (string memory);
function symbol() external view returns (string memory);

/**
 * @dev Returns the amount of tokens owned by `account`.
 */
function balanceOf(address account) external view returns (uint256);

/**
 * @dev Moves `amount` tokens from the caller's account to `recipient`.
 *
 * Returns a boolean value indicating whether the operation succeeded.
 *
 * Emits a {Transfer} event.
 */
function transfer(address recipient, uint256 amount)
external
returns (bool);

/**
 * @dev Returns the remaining number of tokens that `spender` will be
 * allowed to spend on behalf of `owner` through {transferFrom}. This is
 * zero by default.
 *
 * This value changes when {approve} or {transferFrom} are called.
 */
function allowance(address owner, address spender)
external
view
returns (uint256);

/**
 * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
 *
 * Returns a boolean value indicating whether the operation succeeded.
 *
 * IMPORTANT: Beware that changing an allowance with this method brings the risk
 * that someone may use both the old and the new allowance by unfortunate
 * transaction ordering. One possible solution to mitigate this race
 * condition is to first reduce the spender's allowance to 0 and set the
 * desired value afterwards:
 * 
 *
 * Emits an {Approval} event.
 */
function approve(address spender, uint256 amount) external returns (bool);

/**
 * @dev Moves `amount` tokens from `sender` to `recipient` using the
 * allowance mechanism. `amount` is then deducted from the caller's
 * allowance.
 *
 * Returns a boolean value indicating whether the operation succeeded.
 *
 * Emits a {Transfer} event.
 */
function transferFrom(
    address sender,
    address recipient,
    uint256 amount
) external returns (bool);

/**
 * @dev Emitted when `value` tokens are moved from one account (`from`) to
 * another (`to`).
 *
 * Note that `value` may be zero.
 */
event Transfer(address indexed from, address indexed to, uint256 value);

/**
 * @dev Emitted when the allowance of a `spender` for an `owner` is set by
 * a call to {approve}. `value` is the new allowance.
 */
event Approval(
    address indexed owner,
    address indexed spender,
    uint256 value
);

}

contract Ownable {

address private _owner;

event OwnershipTransferred(
    address indexed previousOwner,
    address indexed newOwner
);

function _msgSender() internal view virtual returns (address) {
    return msg.sender;
}

function _msgData() internal view virtual returns (bytes memory) {
    this;
    
    return msg.data;
}

constructor() {
    address msgSender = _msgSender();
    _owner = msgSender;
    emit OwnershipTransferred(address(0), msgSender);
}

function owner() public view returns (address) {
    return _owner;
}

modifier onlyOwner() {
    require(_owner == _msgSender(), "Ownable: caller is not the owner");
    _;
}

function renounceOwnership() public virtual onlyOwner {
    emit OwnershipTransferred(_owner, address(0));
    _owner = address(0);
}

function transferOwnership(address newOwner) public virtual onlyOwner {
    require(
        newOwner != address(0),
        "Ownable: new owner is the zero address"
    );
    emit OwnershipTransferred(_owner, newOwner);
    _owner = newOwner;
}

}

library Address {

function isContract(address account) internal view returns (bool) {
    bytes32 codehash;
    bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
    // solhint-disable-next-line no-inline-assembly
    assembly { codehash := extcodehash(account) }
    return (codehash != 0x0 && codehash != accountHash);
}

}

contract UsdtWrap {

IERC20 public token520;
IERC20 public usdt;

constructor (IERC20 _token520)  {
    token520 = _token520;
    usdt = IERC20(0x55d398326f99059fF775485246999027B3197955);
}

function withdraw() public {
    uint256 usdtBalance = usdt.balanceOf(address(this));
    if (usdtBalance > 0) {
        usdt.transfer(address(token520), usdtBalance);
    }
    uint256 token520Balance = token520.balanceOf(address(this));
    if (token520Balance > 0) {
        token520.transfer(address(token520), token520Balance);
    }
}

}

contract ERC20 is Ownable, IERC20 {

using SafeMath for uint256;

mapping(address => uint256) private _balances;

mapping(address => mapping(address => uint256)) private _allowances;

uint256 private _totalSupply;

string private _name;
string private _symbol;

/**
 * @dev Sets the values for {name} and {symbol}.
 *
 * The default value of {decimals} is 18. To select a different value for
 * {decimals} you should overload it.
 *
 * All two of these values are immutable: they can only be set once during
 * construction.
 */
constructor(string memory name_, string memory symbol_) {
    _name = name_;
    _symbol = symbol_;

}

/**
 * @dev Returns the name of the token.
 */
function name() public view virtual override returns (string memory) {
    return _name;
}

/**
 * @dev Returns the symbol of the token, usually a shorter version of the
 * name.
 */
function symbol() public view virtual override returns (string memory) {
    return _symbol;
}

/**
 * @dev Returns the number of decimals used to get its user representation.
 * For example, if `decimals` equals `2`, a balance of `505` tokens should
 * be displayed to a user as `5,05` (`505 / 10 ** 2`).
 *
 * Tokens usually opt for a value of 18, imitating the relationship between
 * Ether and Wei. This is the value {ERC20} uses, unless this function is
 * overridden;
 *
 * NOTE: This information is only used for _display_ purposes: it in
 * no way affects any of the arithmetic of the contract, including
 * {IERC20-balanceOf} and {IERC20-transfer}.
 */
function decimals() public view virtual override returns (uint8) {
    return 18;
}

/**
 * @dev See {IERC20-totalSupply}.
 */
function totalSupply() public view virtual override returns (uint256) {
    return _totalSupply;
}

/**
 * @dev See {IERC20-balanceOf}.
 */
  function balanceOf(address account) public view override returns (uint256) {
    return _balances[account];
}

/**
 * @dev See {IERC20-transfer}.
 *
 * Requirements:
 *
 * - `recipient` cannot be the zero address.
 * - the caller must have a balance of at least `amount`.
 */
function transfer(address recipient, uint256 amount)
public
virtual
override
returns (bool)
{
    _transfer(_msgSender(), recipient, amount);
    return true;
}

/**
 * @dev See {IERC20-allowance}.
 */
function allowance(address owner, address spender)
public
view
virtual
override
returns (uint256)
{
    return _allowances[owner][spender];
}

/**
 * @dev See {IERC20-approve}.
 *
 * Requirements:
 *
 * - `spender` cannot be the zero address.
 */
function approve(address spender, uint256 amount)
public
virtual
override
returns (bool)
{
    _approve(_msgSender(), spender, amount);
    return true;
}

/**
 * @dev See {IERC20-transferFrom}.
 *
 * Emits an {Approval} event indicating the updated allowance. This is not
 * required by the EIP. See the note at the beginning of {ERC20}.
 *
 * Requirements:
 *
 * - `sender` and `recipient` cannot be the zero address.
 * - `sender` must have a balance of at least `amount`.
 * - the caller must have allowance for ``sender``'s tokens of at least
 * `amount`.
 */
function transferFrom(
    address sender,
    address recipient,
    uint256 amount
) public virtual override returns (bool) {
    _transfer(sender, recipient, amount);
    _approve(
        sender,
        _msgSender(),
        _allowances[sender][_msgSender()].sub(
            amount,
            "ERC20: transfer amount exceeds allowance"
        )
    );
    return true;
}

/**
 * @dev Atomically increases the allowance granted to `spender` by the caller.
 *
 * This is an alternative to {approve} that can be used as a mitigation for
 * problems described in {IERC20-approve}.
 *
 * Emits an {Approval} event indicating the updated allowance.
 *
 * Requirements:
 *
 * - `spender` cannot be the zero address.
 */
function increaseAllowance(address spender, uint256 addedValue)
public
virtual
returns (bool)
{
    _approve(
        _msgSender(),
        spender,
        _allowances[_msgSender()][spender].add(addedValue)
    );
    return true;
}

/**
 * @dev Atomically decreases the allowance granted to `spender` by the caller.
 *
 * This is an alternative to {approve} that can be used as a mitigation for
 * problems described in {IERC20-approve}.
 *
 * Emits an {Approval} event indicating the updated allowance.
 *
 * Requirements:
 *
 * - `spender` cannot be the zero address.
 * - `spender` must have allowance for the caller of at least
 * `subtractedValue`.
 */
function decreaseAllowance(address spender, uint256 subtractedValue)
public
virtual
returns (bool)
{
    _approve(
        _msgSender(),
        spender,
        _allowances[_msgSender()][spender].sub(
            subtractedValue,
            "ERC20: decreased allowance below zero"
        )
    );
    return true;
}

/**
 * @dev Moves tokens `amount` from `sender` to `recipient`.
 *
 * This is internal function is equivalent to {transfer}, and can be used to
 * e.g. implement automatic token fees, slashing mechanisms, etc.
 *
 * Emits a {Transfer} event.
 *
 * Requirements:
 *
 * - `sender` cannot be the zero address.
 * - `recipient` cannot be the zero address.
 * - `sender` must have a balance of at least `amount`.
 */
function _transfer(
    address sender,
    address recipient,
    uint256 amount
) internal virtual {
    require(sender != address(0), "ERC20: transfer from the zero address");
    require(recipient != address(0), "ERC20: transfer to the zero address");

    _beforeTokenTransfer(sender, recipient, amount);

     _transferToken(sender,recipient,amount);
}

function _transferToken(
    address sender,
    address recipient,
    uint256 amount
) internal virtual {
    _balances[sender] = _balances[sender].sub(
        amount,
        "ERC20: transfer amount exceeds balance"
    );
    _balances[recipient] = _balances[recipient].add(amount);
    emit Transfer(sender, recipient, amount);
}

/** @dev Creates `amount` tokens and assigns them to `account`, increasing
 * the total supply.
 *
 * Emits a {Transfer} event with `from` set to the zero address.
 *
 * Requirements:
 *
 * - `account` cannot be the zero address.
 */
function _mint(address account, uint256 amount) internal virtual {
    require(account != address(0), "ERC20: mint to the zero address");

    _beforeTokenTransfer(address(0), account, amount);

    _totalSupply = _totalSupply.add(amount);
    _balances[account] = _balances[account].add(amount);
    emit Transfer(address(0), account, amount);
}

/**
 * @dev Destroys `amount` tokens from `account`, reducing the
 * total supply.
 *
 * Emits a {Transfer} event with `to` set to the zero address.
 *
 * Requirements:
 *
 * - `account` cannot be the zero address.
 * - `account` must have at least `amount` tokens.
 */
function _burn(address account, uint256 amount) internal virtual {
    require(account != address(0), "ERC20: burn from the zero address");

    _beforeTokenTransfer(account, address(0), amount);

    _balances[account] = _balances[account].sub(
        amount,
        "ERC20: burn amount exceeds balance"
    );
    _totalSupply = _totalSupply.sub(amount);
    emit Transfer(account, address(0), amount);
}



/**
 * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
 *
 * This internal function is equivalent to `approve`, and can be used to
 * e.g. set automatic allowances for certain subsystems, etc.
 *
 * Emits an {Approval} event.
 *
 * Requirements:
 *
 * - `owner` cannot be the zero address.
 * - `spender` cannot be the zero address.
 */
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);
}

/**
 * @dev Hook that is called before any transfer of tokens. This includes
 * minting and burning.
 *
 * Calling conditions:
 *
 * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
 * will be to transferred to `to`.
 * - when `from` is zero, `amount` tokens will be minted for `to`.
 * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
 * - `from` and `to` are never both zero.
 *
 * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
 */
function _beforeTokenTransfer(
    address from,
    address to,
    uint256 amount
) internal virtual {}

}

library SafeMath {

/**
 * @dev Returns the addition of two unsigned integers, reverting on
 * overflow.
 *
 * Counterpart to Solidity's `+` operator.
 *
 * Requirements:
 *
 * - Addition cannot overflow.
 */
function add(uint256 a, uint256 b) internal pure returns (uint256) {
    uint256 c = a + b;
    require(c >= a, "SafeMath: addition overflow");

    return c;
}

/**
 * @dev Returns the subtraction of two unsigned integers, reverting on
 * overflow (when the result is negative).
 *
 * Counterpart to Solidity's `-` operator.
 *
 * Requirements:
 *
 * - Subtraction cannot overflow.
 */
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
    return sub(a, b, "SafeMath: subtraction overflow");
}

/**
 * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
 * overflow (when the result is negative).
 *
 * Counterpart to Solidity's `-` operator.
 *
 * Requirements:
 *
 * - Subtraction cannot overflow.
 */
function sub(
    uint256 a,
    uint256 b,
    string memory errorMessage
) internal pure returns (uint256) {
    require(b <= a, errorMessage);
    uint256 c = a - b;

    return c;
}

/**
 * @dev Returns the multiplication of two unsigned integers, reverting on
 * overflow.
 *
 * Counterpart to Solidity's `*` operator.
 *
 * Requirements:
 *
 * - Multiplication cannot overflow.
 */
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
    // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
    // benefit is lost if 'b' is also tested.
    // See: 
    if (a == 0) {
        return 0;
    }

    uint256 c = a * b;
    require(c / a == b, "SafeMath: multiplication overflow");

    return c;
}

/**
 * @dev Returns the integer division of two unsigned integers. Reverts on
 * division by zero. The result is rounded towards zero.
 *
 * Counterpart to Solidity's `/` operator. Note: this function uses a
 * `revert` opcode (which leaves remaining gas untouched) while Solidity
 * uses an invalid opcode to revert (consuming all remaining gas).
 *
 * Requirements:
 *
 * - The divisor cannot be zero.
 */
function div(uint256 a, uint256 b) internal pure returns (uint256) {
    return div(a, b, "SafeMath: division by zero");
}

/**
 * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
 * division by zero. The result is rounded towards zero.
 *
 * Counterpart to Solidity's `/` operator. Note: this function uses a
 * `revert` opcode (which leaves remaining gas untouched) while Solidity
 * uses an invalid opcode to revert (consuming all remaining gas).
 *
 * Requirements:
 *
 * - The divisor cannot be zero.
 */
function div(
    uint256 a,
    uint256 b,
    string memory errorMessage
) internal pure returns (uint256) {
    require(b > 0, errorMessage);
    uint256 c = a / b;
    // assert(a == b * c + a % b); // There is no case in which this doesn't hold

    return c;
}

/**
 * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
 * Reverts when dividing by zero.
 *
 * Counterpart to Solidity's `%` operator. This function uses a `revert`
 * opcode (which leaves remaining gas untouched) while Solidity uses an
 * invalid opcode to revert (consuming all remaining gas).
 *
 * Requirements:
 *
 * - The divisor cannot be zero.
 */
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
    return mod(a, b, "SafeMath: modulo by zero");
}

/**
 * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
 * Reverts with custom message when dividing by zero.
 *
 * Counterpart to Solidity's `%` operator. This function uses a `revert`
 * opcode (which leaves remaining gas untouched) while Solidity uses an
 * invalid opcode to revert (consuming all remaining gas).
 *
 * Requirements:
 *
 * - The divisor cannot be zero.
 */
function mod(
    uint256 a,
    uint256 b,
    string memory errorMessage
) internal pure returns (uint256) {
    require(b != 0, errorMessage);
    return a % b;
}

}

interface IUniswapV2Router01 {

function factory() external pure returns (address);

function WETH() external pure returns (address);

function addLiquidity(
    address tokenA,
    address tokenB,
    uint256 amountADesired,
    uint256 amountBDesired,
    uint256 amountAMin,
    uint256 amountBMin,
    address to,
    uint256 deadline
)
external
returns (
    uint256 amountA,
    uint256 amountB,
    uint256 liquidity
);

function addLiquidityETH(
    address token,
    uint256 amountTokenDesired,
    uint256 amountTokenMin,
    uint256 amountETHMin,
    address to,
    uint256 deadline
)
external
payable
returns (
    uint256 amountToken,
    uint256 amountETH,
    uint256 liquidity
);

function removeLiquidity(
    address tokenA,
    address tokenB,
    uint256 liquidity,
    uint256 amountAMin,
    uint256 amountBMin,
    address to,
    uint256 deadline
) external returns (uint256 amountA, uint256 amountB);

function removeLiquidityETH(
    address token,
    uint256 liquidity,
    uint256 amountTokenMin,
    uint256 amountETHMin,
    address to,
    uint256 deadline
) external returns (uint256 amountToken, uint256 amountETH);

function removeLiquidityWithPermit(
    address tokenA,
    address tokenB,
    uint256 liquidity,
    uint256 amountAMin,
    uint256 amountBMin,
    address to,
    uint256 deadline,
    bool approveMax,
    uint8 v,
    bytes32 r,
    bytes32 s
) external returns (uint256 amountA, uint256 amountB);

function removeLiquidityETHWithPermit(
    address token,
    uint256 liquidity,
    uint256 amountTokenMin,
    uint256 amountETHMin,
    address to,
    uint256 deadline,
    bool approveMax,
    uint8 v,
    bytes32 r,
    bytes32 s
) external returns (uint256 amountToken, uint256 amountETH);

function swapExactTokensForTokens(
    uint256 amountIn,
    uint256 amountOutMin,
    address[] calldata path,
    address to,
    uint256 deadline
) external returns (uint256[] memory amounts);

function swapTokensForExactTokens(
    uint256 amountOut,
    uint256 amountInMax,
    address[] calldata path,
    address to,
    uint256 deadline
) external returns (uint256[] memory amounts);

function swapExactETHForTokens(
    uint256 amountOutMin,
    address[] calldata path,
    address to,
    uint256 deadline
) external payable returns (uint256[] memory amounts);

function swapTokensForExactETH(
    uint256 amountOut,
    uint256 amountInMax,
    address[] calldata path,
    address to,
    uint256 deadline
) external returns (uint256[] memory amounts);

function swapExactTokensForETH(
    uint256 amountIn,
    uint256 amountOutMin,
    address[] calldata path,
    address to,
    uint256 deadline
) external returns (uint256[] memory amounts);

function swapETHForExactTokens(
    uint256 amountOut,
    address[] calldata path,
    address to,
    uint256 deadline
) external payable returns (uint256[] memory amounts);

function quote(
    uint256 amountA,
    uint256 reserveA,
    uint256 reserveB
) external pure returns (uint256 amountB);

function getAmountOut(
    uint256 amountIn,
    uint256 reserveIn,
    uint256 reserveOut
) external pure returns (uint256 amountOut);

function getAmountIn(
    uint256 amountOut,
    uint256 reserveIn,
    uint256 reserveOut
) external pure returns (uint256 amountIn);

function getAmountsOut(uint256 amountIn, address[] calldata path)
external
view
returns (uint256[] memory amounts);

function getAmountsIn(uint256 amountOut, address[] calldata path)
external
view
returns (uint256[] memory amounts);

}

interface IUniswapV2Router02 is IUniswapV2Router01 {

function removeLiquidityETHSupportingFeeOnTransferTokens(
    address token,
    uint256 liquidity,
    uint256 amountTokenMin,
    uint256 amountETHMin,
    address to,
    uint256 deadline
) external returns (uint256 amountETH);

function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
    address token,
    uint256 liquidity,
    uint256 amountTokenMin,
    uint256 amountETHMin,
    address to,
    uint256 deadline,
    bool approveMax,
    uint8 v,
    bytes32 r,
    bytes32 s
) external returns (uint256 amountETH);

function swapExactTokensForTokensSupportingFeeOnTransferTokens(
    uint256 amountIn,
    uint256 amountOutMin,
    address[] calldata path,
    address to,
    uint256 deadline
) external;

function swapExactETHForTokensSupportingFeeOnTransferTokens(
    uint256 amountOutMin,
    address[] calldata path,
    address to,
    uint256 deadline
) external payable;

function swapExactTokensForETHSupportingFeeOnTransferTokens(
    uint256 amountIn,
    uint256 amountOutMin,
    address[] calldata path,
    address to,
    uint256 deadline
) external;

}

contract Diamond is ERC20 {

using SafeMath for uint256;

IUniswapV2Router02 public uniswapV2Router;
IUniswapV2Pair public  uniswapV2Pair;
address _tokenOwner;
address private marketAddress;
address public teamAddress;
mapping(address => bool) private _isExcludedFromFees;
bool public swapAndLiquifyEnabled = true;
bool private swapping = false;
bool public swapstatus;
bool public checkWalletLimit = true; 

uint256 public lpFee = 30;
uint256 public marketFee = 20;
uint256 public totalFee = lpFee+marketFee;

uint256 public feeAmount = 0;
uint256 public feeTokenAmount = 0;

uint256 public lpDivTokenAmount = 0;
uint256 public lpDivThresAmount = 0;
uint256 public >
uint256 public _walletMax = 5 *10**18;

IERC20 public usdt = IERC20(0x55d398326f99059fF775485246999027B3197955);
IERC20 public  deadAddress =IERC20(0x000000000000000000000000000000000000dEaD);
IERC20 public lpToken;
address[] private lpUser;
mapping(address => bool) public lpPush;
mapping(address => uint256) private lpIndex;
address[] public _exAddress;
mapping(address => bool) private _bexAddress;
mapping(address => uint256) private _exIndex;
mapping(address => bool) public ammPairs;
mapping(address => bool) public whitelist;
mapping(address => bool) public _isBlacklisted;
mapping (address => bool) public isWalletLimitExempt;

address public lastAddress = address(0);
uint256 private lpPos = 0;
uint256 private lpTokenDivThres;
uint256 private divLpHolderAmount;
UsdtWrap RECV;

event ExcludeFromFees(address indexed account, bool isExcluded);
event WhitelistMultipleAddresses(address[] accounts, bool value);
event BlacklistMultipleAddresses(address[] accounts, bool value);
event SwapAndLiquify(
    uint256 tokensSwapped,
    uint256 ethReceived
);

constructor() ERC20("BAOFU Token", "BF") {

    uniswapV2Router = IUniswapV2Router02(0x10ED43C718714eb63d5aA57B78B54704E256024E);
    // Create a uniswap pair for this new token
    _tokenOwner = address(0xed397c22d88f60c20F694ca1B5Bd493DF96Fb09b);
    marketAddress = address(0xed397c22d88f60c20F694ca1B5Bd493DF96Fb09b);
    teamAddress= address(0xed397c22d88f60c20F694ca1B5Bd493DF96Fb09b);
    uniswapV2Pair = IUniswapV2Pair(IUniswapV2Factory(uniswapV2Router.factory()).createPair(address(this), address(usdt)));
    IUniswapV2Pair uniswapV2PairBNB = IUniswapV2Pair(IUniswapV2Factory(uniswapV2Router.factory()).createPair(address(this), uniswapV2Router.WETH()));
    ammPairs[address(uniswapV2Pair)] = true;
    ammPairs[address(uniswapV2PairBNB)] = true;
    isWalletLimitExempt[address(uniswapV2Pair)] = true;
    isWalletLimitExempt[address(this)] = true;
    isWalletLimitExempt[_tokenOwner] = true;
    isWalletLimitExempt[address(deadAddress)] = true;
    _approve(address(this), address(uniswapV2Router), ~uint256(0));
    excludeFromFees(_tokenOwner, true);
    excludeFromFees(address(this), true);
    excludeFromFees(address(uniswapV2Router),true);
    excludeFromFees(marketAddress, true);
    excludeFromFees(teamAddress, true);
    lpToken = usdt;
    RECV = new UsdtWrap(IERC20(address(this)));
    _mint(_tokenOwner, 688 * 10**18);
    divLpHolderAmount = 1 * 10**16;
    lpTokenDivThres = 300 * 10**18;
}

receive() external payable {}

function setFees(uint256 _lpFee,uint256 _marketFee) external onlyOwner{
    lpFee = _lpFee;
    marketFee = _marketFee;
    totalFee = lpFee+marketFee;
}

function setlpDivThres(uint256 _thres) public onlyOwner {
    lpTokenDivThres = _thres;
}

function setSwapStatus(bool status) public onlyOwner {
    swapstatus = status;
}

function setDivLpHolderAmount(uint256 amount) public onlyOwner {
    divLpHolderAmount = amount;
}

function enableDisableWalletLimit(bool newValue) external onlyOwner {
   checkWalletLimit = newValue;
}

function setIsWalletLimitExempt(address holder, bool exempt) external onlyOwner {
    isWalletLimitExempt[holder] = exempt;
}

function setWalletLimit(uint256 newLimit) external onlyOwner {
    _walletMax  = newLimit;
}

function excludeFromFees(address account, bool excluded) public onlyOwner {
    _isExcludedFromFees[account] = excluded;
    emit ExcludeFromFees(account, excluded);
}

function setAmmPairs(address pair, bool isPair) public onlyOwner {
    ammPairs[pair] = isPair;
}
function whitelistMultipleAddresses(address[] calldata accounts, bool value) external onlyOwner {
    for(uint256 i = 0; i < accounts.length; i++) {
        whitelist[accounts[i]] = value;
    }

    emit WhitelistMultipleAddresses(accounts, value);
}

function setWhitelist(address account, bool value) public onlyOwner {
    whitelist[account] = value;
}

function blacklistMultipleAddresses(address[] calldata accounts, bool value) external onlyOwner {
    for(uint256 i = 0; i < accounts.length; i++) {
        _isBlacklisted[accounts[i]] = value;
    }

    emit BlacklistMultipleAddresses(accounts, value);
}

function blacklistAddress(address account, bool value) external onlyOwner{
    _isBlacklisted[account] = value;
}

function lpDividendProc(address[] memory lpAddresses)
    private
{
    for(uint256 i = 0 ;i< lpAddresses.length;i++){
         if(lpPush[lpAddresses[i]] && (uniswapV2Pair.balanceOf(lpAddresses[i]) < divLpHolderAmount||_bexAddress[lpAddresses[i]])){
            _clrLpDividend(lpAddresses[i]);
         }else if(!Address.isContract(lpAddresses[i]) && !lpPush[lpAddresses[i]] && !_bexAddress[lpAddresses[i]]&& uniswapV2Pair.balanceOf(lpAddresses[i]) >= divLpHolderAmount){
            _setLpDividend(lpAddresses[i]);
         }
    }
}

function setExAddress(address exa) public onlyOwner {
    require( !_bexAddress[exa]);
    _bexAddress[exa] = true;
    _exIndex[exa] = _exAddress.length;
    _exAddress.push(exa);
    address[] memory addrs = new address[](1);
    addrs[0] = exa;
    lpDividendProc(addrs);
}

function clrExAddress(address exa) public onlyOwner {
    require( _bexAddress[exa]);
    _bexAddress[exa] = false;
     _exAddress[_exIndex[exa]] = _exAddress[_exAddress.length-1];
    _exIndex[_exAddress[_exAddress.length-1]] = _exIndex[exa];
    _exIndex[exa] = 0;
    _exAddress.pop();
    address[] memory addrs = new address[](1);
    addrs[0] = exa;
    lpDividendProc(addrs);
}

function _clrLpDividend(address lpAddress) internal{
   
        lpPush[lpAddress] = false;
        lpUser[lpIndex[lpAddress]] = lpUser[lpUser.length-1];
        lpIndex[lpUser[lpUser.length-1]] = lpIndex[lpAddress];
        lpIndex[lpAddress] = 0;
        lpUser.pop();
}

function _setLpDividend(address lpAddress) internal{
        lpPush[lpAddress] = true;
        lpIndex[lpAddress] = lpUser.length;
        lpUser.push(lpAddress);
}

function setSwapAndLiquifyEnabled(bool _enabled) public onlyOwner {
    swapAndLiquifyEnabled = _enabled;
}

function setTeamAddress(address payable newWallet) external onlyOwner{
    teamAddress = newWallet;
}

function isExcludedFromFees(address account) public view returns (bool) {
    return _isExcludedFromFees[account];
}

function _transfer(
    address from,
    address to,
    uint256 amount
) internal override {
    require(from != address(0), "ERC20: transfer from the zero address");
    require(to != address(0), "ERC20: transfer to the zero address");
    require(!_isBlacklisted[from] && !_isBlacklisted[to], 'Blacklisted address');
    if((ammPairs[from]  || ammPairs[to]) && swapstatus == false){
        require(whitelist[from] || whitelist[to],"only whitelist!");
    }
    

    if( uniswapV2Pair.totalSupply() > 0 && balanceOf(address(this)) > balanceOf(address(uniswapV2Pair)).div(10000) && to == address(uniswapV2Pair)){
        if (
            !swapping &&
            _tokenOwner != from &&
            _tokenOwner != to &&
            !ammPairs[from] &&
            !(from == address(uniswapV2Router) && !ammPairs[to])&&
            swapAndLiquifyEnabled
        ) {
            swapping = true;
            swapProc();
            swapping = false;
        }
    }
    
    if(ammPairs[to])
    {
          uint256 balance = balanceOf(from);
          if (amount == balance) {
            amount = amount.sub(amount.div(1000));
        }
        
    }

    bool takeFee = !swapping;

    if (_isExcludedFromFees[from] || _isExcludedFromFees[to]) {
        takeFee = false;
    }else {
        
        if((!ammPairs[from] && !ammPairs[to])){
            takeFee = false;
        }
        if(!ammPairs[from])
            amount = amount.mul(999).div(1000); 
    }
    if (takeFee) { 
        if(ammPairs[to] || ammPairs[from]){
            uint256 share = amount.div(1000);
            super._transfer(from, address(this), share.mul(totalFee));
            feeAmount = feeAmount.add(share.mul(totalFee));
            amount = amount.sub(share.mul(totalFee));
        }
    }

    if(checkWalletLimit && !isWalletLimitExempt[to])
            require(balanceOf(to).add(amount) <= _walletMax);

    super._transfer(from, to, amount);

    if(lastAddress == address(0)){
        address[] memory addrs = new address[](2);
        addrs[0] = from;
        addrs[1] = to;
        lpDividendProc(addrs);
    }else{
        address[] memory addrs = new address[](3);
        addrs[0] = from;
        addrs[1] = to;
        addrs[2] = lastAddress;
        lastAddress = address(0);
        lpDividendProc(addrs);
    }
    if(ammPairs[to]){
        lastAddress = from;
    }

    if(!swapping && _tokenOwner != from && _tokenOwner != to){
        _splitlpToken();
    }
    
}

function swapProc() public {
    uint256 canSellAmount = feeAmount.sub(feeTokenAmount);
    uint256 amountT = balanceOf(address(uniswapV2Pair)).div(10000);
    if(balanceOf(address(this)) >= canSellAmount && canSellAmount >= amountT){
        if(canSellAmount >= amountT.mul(300))
            canSellAmount = amountT.mul(300);
        feeTokenAmount = feeTokenAmount.add(canSellAmount);
        uint256 beforeBal = IERC20(usdt).balanceOf(address(this));
        swapTokensForUSDT(canSellAmount);
        uint256 newBal = IERC20(usdt).balanceOf(address(this)).sub(beforeBal);
        uint256 marketAmount = newBal.mul(marketFee).div(marketFee+lpFee);
        IERC20(usdt).transfer(marketAddress,marketAmount.div(2));
        IERC20(usdt).transfer(teamAddress,marketAmount.div(2));
        lpDivTokenAmount = IERC20(usdt).balanceOf(address(this));    
    }
}

function swapTokensForUSDT(uint256 tokenAmount) private {
    // generate the uniswap pair path of token -> weth
    address[] memory path = new address[](2);
    path[0] = address(this);
    path[1] = address(usdt);
    // make the swap
    uniswapV2Router.swapExactTokensForTokensSupportingFeeOnTransferTokens(
        tokenAmount,
        0, // accept any amount of ETH
        path,
        address(RECV),
        block.timestamp
    );

    RECV.withdraw();
}

function rescueToken(address tokenAddress, uint256 tokens)
public
onlyOwner
returns (bool success)
{
    return IERC20(tokenAddress).transfer(msg.sender, tokens);
}



function _splitlpToken() private {
    uint256 thisAmount = lpDivTokenAmount;
    if(thisAmount < lpTokenDivThres) return;
    if(lpPos >= lpUser.length)  lpPos = 0;
    if(lpUser.length > 0 ){
            uint256 procMax = oneDividendNum;
            if(lpPos + oneDividendNum > lpUser.length)
                    procMax = lpUser.length - lpPos;
            uint256 procPos = lpPos + procMax;
            for(uint256 i = lpPos;i < procPos && i < lpUser.length;i++){
                if(uniswapV2Pair.balanceOf(lpUser[i]) < divLpHolderAmount){
                    _clrLpDividend(lpUser[i]);
                }
            }
    }
    if(lpUser.length == 0) return;      
    uint256 totalAmount = 0;
    uint256 num = lpUser.length >= oneDividendNum ? oneDividendNum:lpUser.length;
    totalAmount = uniswapV2Pair.totalSupply();
    for(uint256 i = 0; i < _exAddress.length;i++){
        totalAmount = totalAmount.sub(uniswapV2Pair.balanceOf(_exAddress[i]));
    }
    if(totalAmount == 0) return;
    uint256 resDivAmount = thisAmount;
    uint256 dAmount;
    for(uint256 i=0;i<num;i++){
        address user = lpUser[(lpPos+i).mod(lpUser.length)];
        if(user != address(0xdead) ){
            if(uniswapV2Pair.balanceOf(user) >= divLpHolderAmount){
                dAmount = uniswapV2Pair.balanceOf(user).mul(thisAmount).div(totalAmount);
                if(dAmount>0){
                    lpToken.transfer(user,dAmount);
                    resDivAmount = resDivAmount.sub(dAmount);
                }
            }
        }
    }
    lpPos = (lpPos+num).mod(lpUser.length);
    lpDivTokenAmount = resDivAmount;
}

function getlpsize() public view returns (uint256) {
    return lpUser.length;
}

}

相关文章
|
7月前
|
存储 安全 分布式数据库
BRC20铭文跨链智能合约系统开发案例详细/需求说明/指南步骤/方案逻辑/源码平台
BRC20铭文跨链系统是一种基于区块链的跨链转账系统。下面是BRC20铭文跨链系统开发方案设计的详细解释:
|
安全 区块链
ARB链智能合约开发运营版丨ARB链智能合约系统开发详细程序/步骤指南/方案逻辑/源码出售
Environment construction: Before developing a smart contract system on the ARB chain, a corresponding development environment needs to be established. This may include setting up nodes for the ARB chain, development tools, and testing networks.
|
7月前
|
安全 区块链
dapp/defi智能合约质押分红系统开发详细功能/案例步骤/需求逻辑/源码指南
Developing a DApp/DeFi smart contract staking dividend system involves multiple technical and functional requirements. The following are possible detailed development steps and functional requirements for your reference
|
运维 监控 测试技术
Arbitrum(ARB链)公链智能合约系统开发方案逻辑/成熟技术/方案项目/源码出售
Arbitrum(ARB链)是一种二级扩展解决方案,用于构建可扩展、低费用的区块链应用。
|
存储 区块链 安全
OP链上智能合约质押项目系统开发(项目方案)技术原理
去中心化金融需要去中心化的发行方式与之匹配,从而完善去中心化金融闭环
|
算法 数据处理 调度
(DeFi、DEX、去中心化游戏)矩阵公排系统DAPP合约逻辑部署源代码详情
// 构造函数,初始化矩阵的行数和列数 constructor(uint256 _rowCount, uint256 _columnCount) { rowCount = _rowCount; columnCount = _columnCount;
dapp丨defi代币合约质押项目系统开发逻辑详细/规则说明/案例设计/步骤细节/源码程序
The smart contract liquidity mining system is a financial application system based on smart contract technology, aimed at providing liquidity and receiving rewards by injecting users' funds into the liquidity pool and locking them in the smart contract.
|
存储 安全 算法
dapp公链游戏链上合约系统开发技术详细/案例开发/方案逻辑/成熟技术
  随着区块链技术的不断发展和普及,越来越多的游戏开发商开始将区块链技术应用于游戏中。区块链游戏系统开发可以带来许多好处,例如提高游戏的安全性、透明度、公正性等,同时还可以让玩家拥有更好的游戏体
|
前端开发 安全 Java
BSC链DAPP智能合约NFTswap/IPPswap/Defiswap/OMNIswap系统开发(开发方案)/项目程序/案例源码
  什么是智能合约DApp   智能合约DApp是计算机程序,通过它,交易双方可以共同完成交易。如果在执行过程中发生了一系列变化,那么智能合约将会记录这些变化并自动执行这些变化。
|
安全 区块链
DAPP代币合约BSC链系统开发详细程序丨BSC链DAPP合约代币系统开发(项目案例)及源码逻辑
  Dapp的核心是智能合约,它定义了应用程序在区块链上运行的规则和逻辑。在设计智能合约时,需要仔细考虑业务逻辑,并确保安全性和可靠性。使用Solidity等语言编写智能合约,并进行测试和部署。