文件 1 的 1:PASSTHELOOT.sol
pragma solidity ^0.8.11;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
}
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
library SafeMath {
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
uint256 c = a / b;
return c;
}
}
contract Ownable is Context {
address private m_Owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor () {
address msgSender = _msgSender();
m_Owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
function owner() public view returns (address) {
return m_Owner;
}
function transferOwnership(address _newOwner) public virtual onlyOwner {
emit OwnershipTransferred(m_Owner, _newOwner);
m_Owner = _newOwner;
}
modifier onlyOwner() {
require(_msgSender() == m_Owner, "Ownable: caller is not the owner");
_;
}
}
interface IUniswapV2Factory {
function createPair(address tokenA, address tokenB) external returns (address pair);
}
interface IUniswapV2Router02 {
function swapExactTokensForETHSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
function factory() external pure returns (address);
function WETH() external pure returns (address);
function addLiquidityETH(
address token,
uint amountTokenDesired,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external payable returns (uint amountToken, uint amountETH, uint liquidity);
}
interface IWETH {
function deposit() external payable;
}
interface FTPAntiBot {
function scanAddress(address _sender, address _recipient, address _safeAddress, address _origin) external returns (bool);
function registerBlock(address _recipient, address _sender, address _origin) external;
}
contract PASSTHELOOT is IERC20, Ownable {
using SafeMath for uint256;
uint256 private constant TOTAL_SUPPLY = 69000 * 10**18;
string private m_Name = "Pass the Loot";
string private m_Symbol = "LOOT";
uint8 private m_Decimals = 18;
address private m_UniswapV2Pair;
address private m_Controller;
address payable private m_MarketingWallet;
IUniswapV2Router02 private m_UniswapV2Router;
uint256 private m_TxLimit = TOTAL_SUPPLY.div(400);
uint256 private m_WalletLimit = TOTAL_SUPPLY.div(80);
bool private m_Liquidity = false;
FTPAntiBot private AntiBot;
address private m_AntibotSvcAddress = 0x2d2230185B24aF94FeEba779CA11Ff6f96d17e6D;
mapping (address => bool) private m_ExcludedAddresses;
mapping (address => uint256) private m_Balances;
mapping (uint256 => uint256) private m_RaffleTaxAmountVotes;
mapping (uint256 => uint256) private m_LargestTaxAmountVotes;
mapping (uint256 => uint256) private m_IntervalVote;
mapping (uint256 => mapping (address => uint256)) private m_BuyerId;
mapping (uint256 => mapping (address => uint256)) private m_VoterIdx;
mapping (address => mapping (address => uint256)) private m_Allowances;
mapping (uint256 => mapping (uint256 => uint256)) private m_GenericVote;
mapping (address => uint256) m_Earnings;
uint256 private m_Launched;
uint256 private pMax = 100000;
uint256 private m_RoundStart;
uint256 private m_Interval = 900;
uint256 private m_RaffleTax = 3000;
uint256 private m_LargestBuyerTax = 2000;
uint256 private m_GenericIdx = 0;
uint256 private m_MarketingTax = 3000;
uint256 private m_Round;
uint256 private m_DAOmin = TOTAL_SUPPLY.div(1000);
uint256 private m_VoteCycle = 1;
uint256 private m_TotalWinnings;
bool private m_AntiBot = false;
address[] private m_Winners;
uint256[] private m_Winnings;
struct Buyer {
address addr;
uint256 amount;
bool eligible;
}
struct Vote {
uint256 interval;
uint256 raffleTax;
uint256 biggestTax;
uint256 generic;
}
struct GameState {
uint256 round;
uint256 gameInterval;
uint256 raffleTax;
uint256 biggestBuyerTax;
}
mapping (uint256 => Buyer[]) private m_Raffle;
mapping (uint256 => Vote[]) private m_Voters;
receive() external payable {}
constructor () {
m_Launched = block.timestamp.add(69 days);
AntiBot = FTPAntiBot(m_AntibotSvcAddress);
m_Controller = msg.sender;
m_MarketingWallet = payable(msg.sender);
m_Winners.push(address(0));
m_Winnings.push(0);
m_Raffle[0].push(Buyer(address(0),0,false));
m_Voters[m_VoteCycle].push(Vote(0,0,0,0));
m_Balances[address(this)] = TOTAL_SUPPLY;
m_ExcludedAddresses[owner()] = true;
m_ExcludedAddresses[address(this)] = true;
emit Transfer(address(0), address(this), TOTAL_SUPPLY);
}
function name() public view returns (string memory) {
return m_Name;
}
function symbol() public view returns (string memory) {
return m_Symbol;
}
function decimals() public view returns (uint8) {
return m_Decimals;
}
function totalSupply() public pure override returns (uint256) {
return TOTAL_SUPPLY;
}
function balanceOf(address _account) public view override returns (uint256) {
return m_Balances[_account];
}
function transfer(address _recipient, uint256 _amount) public override returns (bool) {
_transfer(_msgSender(), _recipient, _amount);
return true;
}
function allowance(address _owner, address _spender) public view override returns (uint256) {
return m_Allowances[_owner][_spender];
}
function approve(address _spender, uint256 _amount) public override returns (bool) {
_approve(_msgSender(), _spender, _amount);
return true;
}
function transferFrom(address _sender, address _recipient, uint256 _amount) public override returns (bool) {
_transfer(_sender, _recipient, _amount);
_approve(_sender, _msgSender(), m_Allowances[_sender][_msgSender()].sub(_amount, "ERC20: transfer amount exceeds allowance"));
return true;
}
function _isBuy(address _sender) private view returns (bool) {
return _sender == m_UniswapV2Pair;
}
function _isSell(address _recipient) private view returns (bool) {
return _recipient == m_UniswapV2Pair;
}
function _trader(address _sender, address _recipient) private view returns (bool) {
return !(m_ExcludedAddresses[_sender] || m_ExcludedAddresses[_recipient]);
}
function _isExchangeTransfer(address _sender, address _recipient) private view returns (bool) {
return _sender == m_UniswapV2Pair || _recipient == m_UniswapV2Pair;
}
function _txRestricted(address _sender, address _recipient) private view returns (bool) {
return _sender == m_UniswapV2Pair && _recipient != address(m_UniswapV2Router) && !m_ExcludedAddresses[_recipient];
}
function _walletCapped(address _recipient) private view returns (bool) {
return _recipient != m_UniswapV2Pair && _recipient != address(m_UniswapV2Router);
}
function _checkTX() private view returns (uint256){
if(block.timestamp <= m_Launched.add(15 minutes))
return TOTAL_SUPPLY.div(400);
else
return TOTAL_SUPPLY;
}
function _approve(address _owner, address _spender, uint256 _amount) private {
require(_owner != address(0), "ERC20: approve from the zero address");
require(_spender != address(0), "ERC20: approve to the zero address");
m_Allowances[_owner][_spender] = _amount;
emit Approval(_owner, _spender, _amount);
}
function _transfer(address _sender, address _recipient, uint256 _amount) private {
require(_sender != address(0), "ERC20: transfer from the zero address");
require(_amount > 0, "Transfer amount must be greater than zero");
if(m_AntiBot && _isExchangeTransfer(_sender, _recipient)) {
require(!AntiBot.scanAddress(_sender, _recipient, m_UniswapV2Pair, tx.origin), "Beep Beep Boop, You're a piece of poop");
AntiBot.registerBlock(_sender, _recipient, tx.origin);
}
if(_walletCapped(_recipient))
require(balanceOf(_recipient) < m_WalletLimit);
uint256 _taxes = 0;
if (_trader(_sender, _recipient)) {
_taxes = _amount.div(pMax.div(_getTaxDenominator()));
require(block.timestamp >= m_Launched);
if (_txRestricted(_sender, _recipient))
require(_amount <= _checkTX());
}
_updateBalances(_sender, _recipient, _amount, _taxes);
}
function _updateBalances(address _sender, address _recipient, uint256 _amount, uint256 _taxes) private {
uint256 _netAmount = _amount.sub(_taxes);
_updateDAO(_sender, _amount);
m_Balances[_sender] = m_Balances[_sender].sub(_amount);
m_Balances[_recipient] = m_Balances[_recipient].add(_netAmount);
m_Balances[address(this)] = m_Balances[address(this)].add(_taxes);
if(_isBuy(_sender))
_trackBuy(_recipient, _netAmount);
else if(_isSell(_recipient))
_trackSell(_sender);
else{
_trackSell(_sender);
_trackBuy(_recipient, _netAmount);
}
emit Transfer(_sender, _recipient, _netAmount);
}
function addLiquidity() external onlyOwner() {
require(!m_Liquidity,"Liquidity already added.");
IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);
m_UniswapV2Router = _uniswapV2Router;
_approve(address(this), address(m_UniswapV2Router), TOTAL_SUPPLY);
m_UniswapV2Pair = IUniswapV2Factory(_uniswapV2Router.factory()).createPair(address(this), _uniswapV2Router.WETH());
m_UniswapV2Router.addLiquidityETH{value: address(this).balance}(address(this),balanceOf(address(this)),0,0,owner(),block.timestamp);
IERC20(m_UniswapV2Pair).approve(address(m_UniswapV2Router), type(uint).max);
m_Liquidity = true;
}
function launch(uint256 _timer) external onlyOwner() {
m_Launched = block.timestamp.add(_timer);
m_AntiBot = true;
m_Round = 1;
m_RoundStart = m_Launched;
m_Raffle[m_Round].push(Buyer(address(0),0,false));
}
function _updateDAO(address _sender, uint256 _amount) private {
uint256 _senderBal = balanceOf(_sender);
if(_sender != m_UniswapV2Pair && _sender != address(this)){
if(_senderBal > m_DAOmin){
if(_senderBal.sub(_amount) < m_DAOmin){
_cleanVotes(_sender);
}
}
}
}
function _cleanVotes(address _sender) private {
if(m_VoterIdx[m_VoteCycle][msg.sender] != 0){
delete m_Voters[m_VoteCycle][m_VoterIdx[m_VoteCycle][_sender]];
m_VoterIdx[m_VoteCycle][msg.sender] = 0;
}
}
function _trackBuy(address _recipient,uint256 _amount) private {
if(m_BuyerId[m_Round][_recipient] != 0){
m_Raffle[m_Round][m_BuyerId[m_Round][_recipient]].amount += _amount;
}
else{
m_Raffle[m_Round].push(Buyer(_recipient, _amount, true));
m_BuyerId[m_Round][_recipient] = m_Raffle[m_Round].length - 1;
}
}
function _trackSell(address _sender) private {
if(m_BuyerId[m_Round][_sender] != 0)
m_Raffle[m_Round][m_BuyerId[m_Round][_sender]].eligible = false;
else{
m_Raffle[m_Round].push(Buyer(_sender, 0, false));
m_BuyerId[m_Round][_sender] = m_Raffle[m_Round].length - 1;
}
}
function _swapTokensForETH(uint256 _amount) private {
address[] memory _path = new address[](2);
_path[0] = address(this);
_path[1] = m_UniswapV2Router.WETH();
_approve(address(this), address(m_UniswapV2Router), _amount);
m_UniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(
_amount,
0,
_path,
address(this),
block.timestamp
);
}
function _disperseETH(address[] memory _winners, address _specialWinner, uint256 _invalid) private {
uint256 _bal = address(this).balance;
if(_invalid == 0){
uint256 _denom = _getTaxDenominator();
uint256 _marketingShare = _bal.mul(m_MarketingTax).div(_denom);
uint256 _share = _bal.mul(m_RaffleTax).div(_denom).div(_winners.length);
uint256 _largestShare = _bal.mul(m_LargestBuyerTax).div(_denom).div(_winners.length);
if (_marketingShare > 0) {
m_MarketingWallet.transfer(_marketingShare);
_bal = _bal.sub(_marketingShare);
}
m_TotalWinnings += _bal;
if(_share > 0){
for(uint256 i=0; i<_winners.length; i++){
if(_share > address(this).balance)
_share = address(this).balance;
if(m_Raffle[m_Round][m_BuyerId[m_Round][_winners[i]]].eligible){
m_Winners.push(_winners[i]);
m_Winnings.push(_share);
m_Earnings[_winners[i]] += _share;
payable(_winners[i]).transfer(_share);
}
_bal = _bal.sub(_share);
}
}
if(_specialWinner != address(0) && _largestShare > 0){
if(_largestShare > address(this).balance)
_largestShare = address(this).balance;
if(m_Raffle[m_Round][m_BuyerId[m_Round][_specialWinner]].eligible){
m_Winners.push(_specialWinner);
m_Winnings.push(_bal);
m_Earnings[_specialWinner] += _bal;
payable(_specialWinner).transfer(_bal);
}
}
}
else
m_MarketingWallet.transfer(_bal.div(_invalid));
}
function _getTaxDenominator() private view returns (uint256) {
uint256 _ret = m_MarketingTax;
_ret += m_LargestBuyerTax;
_ret += m_RaffleTax;
return _ret;
}
function _applyRoundSettings(uint256 _raffleTax, uint256 _biggestTax, uint256 _interval) private {
if(m_RaffleTax != _raffleTax)
m_RaffleTax = _raffleTax;
if(m_LargestBuyerTax != _biggestTax)
m_LargestBuyerTax = _biggestTax;
if(m_Interval != _interval)
m_Interval = _interval;
}
function updateMarketingTax(uint256 _value) external onlyOwner() {
m_MarketingTax = _value;
}
function viewWinners() external view returns (address[] memory, uint256[] memory) {
return (m_Winners, m_Winnings);
}
function earningsOf(address _address) external view returns (uint256) {
return m_Earnings[_address];
}
function vote(uint256 _raffle, uint256 _biggest, uint256 _interval) external {
require(balanceOf(msg.sender) >= m_DAOmin);
require(_raffle >= 1000);
require(_raffle <= 7000);
require(_biggest >= 0);
require(_biggest <= 7000);
require(_interval >= 900);
require(_interval <= 86400);
if(m_VoterIdx[m_VoteCycle][msg.sender] == 0){
m_Voters[m_VoteCycle].push(Vote(_interval, _raffle, _biggest, 0));
m_VoterIdx[m_VoteCycle][msg.sender] = m_Voters[m_VoteCycle].length - 1;
}
else{
m_Voters[m_VoteCycle][m_VoterIdx[m_VoteCycle][msg.sender]].raffleTax = _raffle;
m_Voters[m_VoteCycle][m_VoterIdx[m_VoteCycle][msg.sender]].biggestTax = _biggest;
m_Voters[m_VoteCycle][m_VoterIdx[m_VoteCycle][msg.sender]].interval = _interval;
}
}
function voteForGeneric(uint256 _value) external {
require(balanceOf(msg.sender) >= m_DAOmin);
if(m_VoterIdx[m_VoteCycle][msg.sender] == 0){
m_Voters[m_VoteCycle].push(Vote(0, 0, 0, _value));
m_VoterIdx[m_VoteCycle][msg.sender] = m_Voters[m_VoteCycle].length - 1;
}
else
m_Voters[m_VoteCycle][m_VoterIdx[m_VoteCycle][msg.sender]].generic = _value;
}
function getVotes() external view returns (Vote[] memory) {
return m_Voters[m_VoteCycle];
}
function getBuyers() external view returns (Buyer[] memory, Buyer[] memory) {
return (m_Raffle[m_Round-1], m_Raffle[m_Round]);
}
function getGameState() external view returns (GameState memory) {
return GameState(m_Round,m_Interval,m_RaffleTax,m_LargestBuyerTax);
}
function resetGame(address[] memory _winners, address _specialWinner, uint256 _raffleTax, uint256 _biggestTax, uint256 _interval, uint256 _cycle, uint256 _invalid) external {
require(msg.sender == m_Controller);
uint256 _bal = balanceOf(address(this));
_swapTokensForETH(_bal);
_disperseETH(_winners, _specialWinner, _invalid);
_applyRoundSettings(_raffleTax, _biggestTax, _interval);
m_Round += 1;
m_RoundStart = block.timestamp;
m_Raffle[m_Round].push(Buyer(address(0), 0, false));
if (_cycle != m_VoteCycle)
m_Voters[_cycle].push(Vote(0,0,0,0));
m_VoteCycle = _cycle;
}
function getTotalWinnings() external view returns (uint256){
return m_TotalWinnings;
}
function emergencyReclaim() external onlyOwner() {
m_MarketingWallet.transfer(address(this).balance);
}
function toggleAntibot() external onlyOwner() {
if(m_AntiBot){
m_AntiBot = false;
return;
}
m_AntiBot = true;
}
function addTaxWhitelist(address _address) external onlyOwner() {
m_ExcludedAddresses[_address] = true;
}
function remTaxWhitelist(address _address) external onlyOwner() {
m_ExcludedAddresses[_address] = false;
}
function adjustWalletCap(uint256 _factor) external onlyOwner(){
m_WalletLimit = TOTAL_SUPPLY.div(_factor);
}
}