Description:
Decentralized Finance (DeFi) protocol contract providing Mintable, Swap, Liquidity, Factory functionality.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
interface IUniswapV3Factory {
function createPool(address tokenA, address tokenB, uint24 fee) external returns (address pool);
}
interface INonfungiblePositionManager {
struct MintParams {
address token0;
address token1;
uint24 fee;
int24 tickLower;
int24 tickUpper;
uint256 amount0Desired;
uint256 amount1Desired;
uint256 amount0Min;
uint256 amount1Min;
address recipient;
uint256 deadline;
}
function mint(MintParams calldata params) external payable returns (
uint256 tokenId,
uint128 liquidity,
uint256 amount0,
uint256 amount1
);
function createAndInitializePoolIfNecessary(
address token0,
address token1,
uint24 fee,
uint160 sqrtPriceX96
) external payable returns (address pool);
struct CollectParams {
uint256 tokenId;
address recipient;
uint128 amount0Max;
uint128 amount1Max;
}
function collect(CollectParams calldata params) external payable returns (uint256 amount0, uint256 amount1);
}
interface ISwapRouter {
struct ExactInputSingleParams {
address tokenIn;
address tokenOut;
uint24 fee;
address recipient;
uint256 deadline;
uint256 amountIn;
uint256 amountOutMinimum;
uint160 sqrtPriceLimitX96;
}
function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut);
}
interface IERC20 {
function transfer(address to, uint256 amount) external returns (bool);
function transferFrom(address from, address to, uint256 amount) external returns (bool);
function balanceOf(address account) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function totalSupply() external view returns (uint256);
}
interface IWETH {
function deposit() external payable;
function balanceOf(address) external view returns (uint256);
function transfer(address, uint256) external returns (bool);
function approve(address spender, uint256 amount) external returns (bool);
function withdraw(uint256) external;
}
// Simple anti-sniper ERC20 with minimal restrictions
contract AutoAntiSniperERC20 {
string public name;
string public symbol;
uint8 public decimals = 18;
uint256 public totalSupply = 1000000000 * 10**18; // 1 billion tokens
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
// Anti-sniper variables
address public factory;
address public creator;
uint256 public launchTime; // When token was created
uint256 public devBuyWindow = 300; // 5 minutes for dev exclusive access
// Ethereum Uniswap addresses that should always be allowed
address constant POSITION_MANAGER = 0xC36442b4a4522E871399CD717aBDD847Ab11FE88;
address constant SWAP_ROUTER = 0xE592427A0AEce92De3Edee1F18E0157C05861564;
address constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
modifier tradingAllowed() {
// Always allow factory, creator, and core Uniswap contracts
if (msg.sender == creator ||
msg.sender == factory ||
msg.sender == POSITION_MANAGER ||
msg.sender == SWAP_ROUTER ||
tx.origin == creator) {
_;
return;
}
// For everyone else, check dev buy window
if (block.timestamp < launchTime + devBuyWindow) {
revert();
}
_;
}
constructor(string memory _name, string memory _symbol, address _creator) {
name = _name;
symbol = _symbol;
creator = _creator;
factory = msg.sender;
launchTime = block.timestamp; // Record launch time automatically
balanceOf[factory] = totalSupply; // All tokens start in factory
emit Transfer(address(0), factory, totalSupply);
}
function transfer(address to, uint256 amount) external tradingAllowed returns (bool) {
require(to != address(0));
require(balanceOf[msg.sender] >= amount);
balanceOf[msg.sender] -= amount;
balanceOf[to] += amount;
emit Transfer(msg.sender, to, amount);
return true;
}
function approve(address spender, uint256 amount) external returns (bool) {
require(spender != address(0));
allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function transferFrom(address from, address to, uint256 amount) external tradingAllowed returns (bool) {
require(from != address(0));
require(to != address(0));
require(balanceOf[from] >= amount);
require(allowance[from][msg.sender] >= amount);
balanceOf[from] -= amount;
balanceOf[to] += amount;
allowance[from][msg.sender] -= amount;
emit Transfer(from, to, amount);
return true;
}
}
// Enhanced factory with automatic anti-sniper time windows
contract AllTokensToLPFactoryFixed {
struct TokenInfo {
address tokenAddress;
address creator;
string name;
string symbol;
uint256 tokenId;
uint256 createdAt;
address pool;
int24 tickLower;
int24 tickUpper;
uint256 totalFeesETH;
}
TokenInfo[] public allTokens;
mapping(address => TokenInfo[]) public createdTokens;
mapping(uint256 => address) public tokenCreators;
mapping(address => uint256) public creatorFeesETH;
address public platformAdmin;
uint256 public platformFeesETH;
// ETHEREUM MAINNET V3 addresses
address constant POSITION_MANAGER = 0xC36442b4a4522E871399CD717aBDD847Ab11FE88;
address constant SWAP_ROUTER = 0xE592427A0AEce92De3Edee1F18E0157C05861564;
address constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
uint24 constant POOL_FEE = 10000;
// Price range ticks
int24 constant TICK_LOWER = -887200;
int24 constant TICK_UPPER = 207200;
uint256 constant MIN_SWAP_AMOUNT = 1000 * 10**18;
uint256 constant CREATOR_SHARE = 50;
uint256 constant PLATFORM_SHARE = 50;
uint256 constant REQUIRED_ETH = 0.001 ether; // Updated to match mainnet fee
event TokenCreated(address indexed creator, address indexed tokenAddress, string name, string symbol, uint256 tokenId, address pool, int24 tickLower, int24 tickUpper);
event ExcessFundsSent(address indexed creator, uint256 amount, address indexed recipient);
event FeesCollected(uint256 indexed tokenId, uint256 ethAmount, uint256 tokenAmount, uint256 swappedETH);
event TokensDirectToCreator(address indexed creator, address indexed tokenAddress, uint256 amount);
event CreatorWithdraw(address indexed creator, uint256 ethAmount);
event PlatformWithdraw(uint256 ethAmount);
event AllTokensDeposited(address indexed tokenAddress, uint256 totalTokens, uint256 finalBalance);
modifier onlyCreatorOrAdmin(uint256 tokenId) {
address creator = tokenCreators[tokenId];
require(creator != address(0));
require(msg.sender == creator || msg.sender == platformAdmin);
_;
}
constructor() {
platformAdmin = 0x9360c80CA79409b5e315A9791bB0208C02D6ae32;
}
// Calculate sqrt price
function calculateSqrtPriceX96(address token) internal pure returns (uint160) {
bool tokenIsToken0 = token < WETH;
if (tokenIsToken0) {
// token0 = TOKEN, token1 = WETH
return 2505414483750479500000000;
} else {
// token0 = WETH, token1 = TOKEN
return 2505414483750479200000000000000000;
}
}
function createToken(string memory name, string memory symbol) external payable returns (address tokenAddress, uint256 tokenId) {
require(msg.value >= REQUIRED_ETH);
require(bytes(name).length > 0 && bytes(name).length <= 32);
require(bytes(symbol).length > 0 && bytes(symbol).length <= 10);
uint256 liquidityAmount = REQUIRED_ETH;
uint256 excessAmount = msg.value - liquidityAmount;
// Deploy the automatic anti-sniper ERC20 token with salt iteration
tokenAddress = _deployTokenWithValidAddress(name, symbol, msg.sender);
// Create pool and deposit ALL tokens using full range
address pool;
(tokenId, pool) = _createFullRangeLP(tokenAddress, liquidityAmount);
tokenCreators[tokenId] = msg.sender;
// Send excess funds to platform admin
if (excessAmount > 0) {
(bool success, ) = platformAdmin.call{value: excessAmount}("");
require(success);
emit ExcessFundsSent(msg.sender, excessAmount, platformAdmin);
}
// Store token info
TokenInfo memory tokenInfo = TokenInfo({
tokenAddress: tokenAddress,
creator: msg.sender,
name: name,
symbol: symbol,
tokenId: tokenId,
createdAt: block.timestamp,
pool: pool,
tickLower: TICK_LOWER,
tickUpper: TICK_UPPER,
totalFeesETH: 0
});
createdTokens[msg.sender].push(tokenInfo);
allTokens.push(tokenInfo);
emit TokenCreated(msg.sender, tokenAddress, name, symbol, tokenId, pool, TICK_LOWER, TICK_UPPER);
return (tokenAddress, tokenId);
}
// Deploy token with salt iteration to ensure address > WETH
function _deployTokenWithValidAddress(string memory name, string memory symbol, address creator) internal returns (address) {
uint256 saltNonce = 0;
address predictedAddress;
// Keep trying until we get an address > WETH
do {
bytes32 salt = keccak256(abi.encodePacked(name, symbol, creator, block.timestamp, saltNonce));
predictedAddress = _computeCreate2Address(salt, name, symbol, creator);
saltNonce++;
// Prevent infinite loop (should never happen based on our testing)
require(saltNonce < 100, "Could not find valid address");
} while (predictedAddress <= WETH);
// Deploy with the valid salt
bytes32 finalSalt = keccak256(abi.encodePacked(name, symbol, creator, block.timestamp, saltNonce - 1));
return _deployTokenWithSalt(finalSalt, name, symbol, creator);
}
// Compute CREATE2 address without deploying
function _computeCreate2Address(bytes32 salt, string memory name, string memory symbol, address creator) internal view returns (address) {
bytes memory bytecode = abi.encodePacked(
type(AutoAntiSniperERC20).creationCode,
abi.encode(name, symbol, creator)
);
bytes32 hash = keccak256(
abi.encodePacked(
bytes1(0xff),
address(this),
salt,
keccak256(bytecode)
)
);
return address(uint160(uint256(hash)));
}
// Deploy token using CREATE2 with specific salt
function _deployTokenWithSalt(bytes32 salt, string memory name, string memory symbol, address creator) internal returns (address) {
bytes memory bytecode = abi.encodePacked(
type(AutoAntiSniperERC20).creationCode,
abi.encode(name, symbol, creator)
);
address tokenAddress;
assembly {
tokenAddress := create2(0, add(bytecode, 0x20), mload(bytecode), salt)
}
require(tokenAddress != address(0), "Token deployment failed");
require(tokenAddress > WETH, "Invalid token address generated");
return tokenAddress;
}
function _createFullRangeLP(address tokenAddress, uint256 ethAmount) internal returns (uint256 tokenId, address pool) {
// Convert ETH to WETH
IWETH(WETH).deposit{value: ethAmount}();
uint256 totalTokens = IERC20(tokenAddress).balanceOf(address(this));
require(totalTokens == 1000000000 * 10**18);
// Determine token order
bool tokenIsToken0 = tokenAddress < WETH;
address token0 = tokenIsToken0 ? tokenAddress : WETH;
address token1 = tokenIsToken0 ? WETH : tokenAddress;
uint160 sqrtPriceX96 = calculateSqrtPriceX96(tokenAddress);
pool = INonfungiblePositionManager(POSITION_MANAGER).createAndInitializePoolIfNecessary(
token0, token1, POOL_FEE, sqrtPriceX96
);
IERC20(tokenAddress).approve(POSITION_MANAGER, totalTokens);
IWETH(WETH).approve(POSITION_MANAGER, ethAmount);
(tokenId, , ,) = INonfungiblePositionManager(POSITION_MANAGER).mint(
INonfungiblePositionManager.MintParams({
token0: token0,
token1: token1,
fee: POOL_FEE,
tickLower: TICK_LOWER,
tickUpper: TICK_UPPER,
amount0Desired: tokenIsToken0 ? totalTokens : ethAmount,
amount1Desired: tokenIsToken0 ? ethAmount : totalTokens,
amount0Min: 0,
amount1Min: 0,
recipient: address(this),
deadline: block.timestamp + 300
})
);
uint256 finalBalance = IERC20(tokenAddress).balanceOf(address(this));
emit AllTokensDeposited(tokenAddress, totalTokens, finalBalance);
return (tokenId, pool);
}
function collectFees(uint256 tokenId) external onlyCreatorOrAdmin(tokenId) {
INonfungiblePositionManager.CollectParams memory params = INonfungiblePositionManager.CollectParams({
tokenId: tokenId,
recipient: address(this),
amount0Max: type(uint128).max,
amount1Max: type(uint128).max
});
(uint256 amount0, uint256 amount1) = INonfungiblePositionManager(POSITION_MANAGER).collect(params);
if (amount0 == 0 && amount1 == 0) return;
address creator = tokenCreators[tokenId];
uint256 ethAmount = 0;
uint256 tokenAmount = 0;
address tokenAddress;
for (uint i = 0; i < allTokens.length; i++) {
if (allTokens[i].tokenId == tokenId) {
tokenAddress = allTokens[i].tokenAddress;
break;
}
}
bool tokenIsToken0 = tokenAddress < WETH;
if (tokenIsToken0) {
tokenAmount = amount0;
ethAmount = amount1;
} else {
tokenAmount = amount1;
ethAmount = amount0;
}
if (ethAmount > 0) {
IWETH(WETH).withdraw(ethAmount);
}
uint256 swappedETH = 0;
if (tokenAmount >= MIN_SWAP_AMOUNT) {
swappedETH = _swapTokensForETH(tokenAddress, tokenAmount);
// If swap fails, send tokens directly to creator
if (swappedETH == 0 && tokenAmount > 0) {
IERC20(tokenAddress).transfer(creator, tokenAmount);
emit TokensDirectToCreator(creator, tokenAddress, tokenAmount);
}
} else if (tokenAmount > 0) {
// For small amounts, try to swap first
swappedETH = _swapTokensForETH(tokenAddress, tokenAmount);
if (swappedETH == 0) {
// If swap fails, send tokens directly to creator instead of accumulating
IERC20(tokenAddress).transfer(creator, tokenAmount);
emit TokensDirectToCreator(creator, tokenAddress, tokenAmount);
}
}
uint256 totalETH = ethAmount + swappedETH;
if (totalETH > 0) {
uint256 platformETH = (totalETH * PLATFORM_SHARE) / 100;
uint256 creatorETH = totalETH - platformETH;
creatorFeesETH[creator] += creatorETH;
platformFeesETH += platformETH;
for (uint i = 0; i < allTokens.length; i++) {
if (allTokens[i].tokenId == tokenId) {
allTokens[i].totalFeesETH += totalETH;
break;
}
}
}
emit FeesCollected(tokenId, ethAmount, tokenAmount, swappedETH);
}
// CRITICAL: This is the missing function that the frontend expects!
function collectTokenFees(address tokenAddress) external {
// Find all tokens for this creator and collect fees from them
for (uint i = 0; i < allTokens.length; i++) {
if (allTokens[i].tokenAddress == tokenAddress && allTokens[i].creator == msg.sender) {
try this.collectFees(allTokens[i].tokenId) {
} catch {
}
break;
}
}
}
function _swapTokensForETH(address tokenAddress, uint256 tokenAmount) internal returns (uint256 ethReceived) {
if (tokenAmount == 0) return 0;
IERC20(tokenAddress).approve(SWAP_ROUTER, tokenAmount);
try ISwapRouter(SWAP_ROUTER).exactInputSingle(
ISwapRouter.ExactInputSingleParams({
tokenIn: tokenAddress,
tokenOut: WETH,
fee: POOL_FEE,
recipient: address(this),
deadline: block.timestamp + 300,
amountIn: tokenAmount,
amountOutMinimum: 0,
sqrtPriceLimitX96: 0
})
) returns (uint256 amountOut) {
IWETH(WETH).withdraw(amountOut);
return amountOut;
} catch {
return 0;
}
}
function withdrawCreatorFees() external {
uint256 amount = creatorFeesETH[msg.sender];
require(amount > 0);
creatorFeesETH[msg.sender] = 0;
(bool success, ) = msg.sender.call{value: amount}("");
require(success);
emit CreatorWithdraw(msg.sender, amount);
}
function withdrawPlatformFees() external {
require(msg.sender == platformAdmin);
uint256 amount = platformFeesETH;
require(amount > 0);
platformFeesETH = 0;
(bool success, ) = platformAdmin.call{value: amount}("");
require(success);
emit PlatformWithdraw(amount);
}
function getCreatorFees(address creator) external view returns (uint256) {
return creatorFeesETH[creator];
}
function getPlatformFees() external view returns (uint256) {
return platformFeesETH;
}
function getTokenCount() external view returns (uint256) {
return allTokens.length;
}
receive() external payable {}
}
Submitted on: 2025-10-27 11:40:46
Comments
Log in to comment.
No comments yet.