EVM PumpFun智能合约系统源码分析

PumpFun智能合约系统原理

1. 虚拟储备定价机制

PumpFun采用创新的虚拟储备定价机制,这是一种基于Uniswap V2改进的AMM(自动做市商)模型:

  1. 双重储备系统

    • 虚拟储备:用于价格计算和市场调控
    • 实际储备:记录实际的代币和ETH持有量
  2. 价格计算公式

    // 价格计算的核心逻辑
    uint256 pricePerToken = virtualTokenReserves - tokenAmount;
    uint256 totalLiquidity = virtualEthReserves * virtualTokenReserves;
    uint256 newEthReserves = totalLiquidity/pricePerToken;
    uint256 ethCost = newEthReserves - virtualEthReserves;
    
  3. 初始参数设置

    • 初始虚拟代币储备:10^27
    • 初始虚拟ETH储备:3*10^21
    • 代币总供应量:10^27
    • 市值上限:10^23

2. 代币发行机制

  1. 代币创建流程

    用户调用 -> TokenFactory.deployERC20Token()
      ├── 创建ERC20代币
      ├── 记录代币信息
      ├── 授权PumpFun合约
      └── 自动创建交易池
    
  2. 初始化参数

    • 固定初始供应量:10^27
    • 自动创建交易池
    • 预设市值上限

3. 交易机制

  1. 买入机制

    • 检查剩余代币比例(>20%)
    • 计算ETH成本
    • 收取手续费
    • 更新储备状态
    • 检查完成条件
  2. 卖出机制

    • 验证交易状态
    • 计算ETH返还
    • 收取手续费
    • 更新储备状态
  3. 完成条件

    • 市值超过上限
    • 剩余代币比例低于20%

4. 费用系统

  1. 创建费用

    • 创建池子时一次性收取
    • 可配置费用金额
  2. 交易手续费

    • 基于交易金额的百分比
    • 使用基点计算(1 basis point = 0.01%)
    • 费用接收地址可配置

EVM PumpFun智能合约系统源码分析

合约源码及注释

1. PumpFun.sol

// SPDX-License-Identifier: MIT  // 指定开源协议为MIT
pragma solidity ^0.8.24;         // 指定Solidity编译器版本

// 导入OpenZeppelin的防重入和ERC20接口合约
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

// 定义Uniswap V2工厂接口
interface IUniswapV2Factory {
    // 创建交易对的函数
    function createPair(
        address tokenA,    // 代币A地址
        address tokenB     // 代币B地址
    ) external returns (address pair);  // 返回创建的交易对地址
}

// 定义Uniswap V2路由接口
interface IUniswapV2Router02 {
    // 代币换ETH的函数,支持收取转账手续费
    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        uint amountIn,        // 输入代币数量
        uint amountOutMin,    // 最小输出ETH数量
        address[] calldata path,  // 交易路径
        address to,           // 接收地址
        uint deadline        // 截止时间
    ) external;

    // 获取工厂合约地址
    function factory() external pure returns (address);
    
    // 获取WETH合约地址
    function WETH() external pure returns (address);

    // 添加ETH流动性的函数
    function addLiquidityETH(
        address token,           // 代币地址
        uint amountTokenDesired, // 期望添加的代币数量
        uint amountTokenMin,     // 最小代币数量
        uint amountETHMin,       // 最小ETH数量
        address to,              // 接收LP代币的地址
        uint deadline           // 截止时间
    )
        external
        payable
        returns (
            uint amountToken,   // 实际添加的代币数量
            uint amountETH,     // 实际添加的ETH数量
            uint liquidity      // 获得的LP代币数量
        );
}

// PumpFun主合约,继承防重入保护
contract PumpFun is ReentrancyGuard {
    // 允许合约接收ETH
    receive() external payable {}

    // 状态变量声明
    address private owner;                     // 合约拥有者地址
    address private feeRecipient;             // 手续费接收地址
    uint256 private initialVirtualTokenReserves;  // 初始虚拟代币储备
    uint256 private initialVirtualEthReserves;    // 初始虚拟ETH储备
    uint256 private tokenTotalSupply;         // 代币总供应量
    uint256 private mcapLimit;                // 市值上限
    uint256 private feeBasisPoint;            // 手续费基点
    uint256 private createFee;                // 创建池子费用

    IUniswapV2Router02 private uniswapV2Router;  // Uniswap路由器实例

    // 用户信息结构体
    struct Profile {
        address user;    // 用户地址
        Token[] tokens;  // 用户的代币列表
    }

    // 代币信息结构体
    struct Token {
        address tokenMint;            // 代币合约地址
        uint256 virtualTokenReserves; // 虚拟代币储备
        uint256 virtualEthReserves;   // 虚拟ETH储备
        uint256 realTokenReserves;    // 实际代币储备
        uint256 realEthReserves;      // 实际ETH储备
        uint256 tokenTotalSupply;     // 代币总供应量
        uint256 mcapLimit;            // 市值上限
        bool complete;                 // 是否完成标志
    }

    // 代币曲线映射,key为代币地址,value为Token结构体
    mapping (address => Token) public bondingCurve;

    // 事件定义
    event CreatePool(address indexed mint, address indexed user);    // 创建池子事件
    event Complete(address indexed user, address indexed mint, uint256 timestamp);  // 完成事件
    event Trade(                                                     // 交易事件
        address indexed mint,          // 代币地址
        uint256 ethAmount,            // ETH数量
        uint256 tokenAmount,          // 代币数量
        bool isBuy,                   // 是否为买入
        address indexed user,         // 用户地址
        uint256 timestamp,            // 时间戳
        uint256 virtualEthReserves,   // 虚拟ETH储备
        uint256 virtualTokenReserves  // 虚拟代币储备
    );

    // 仅所有者修饰符
    modifier onlyOwner {
        require(msg.sender == owner, "Not Owner");
        _;
    }

    // 构造函数
    constructor(
        address newAddr,    // 新的手续费接收地址
        uint256 feeAmt,     // 创建池子费用
        uint256 basisFee    // 基础手续费率
    ){
        feeRecipient = newAddr;
        createFee = feeAmt;
        feeBasisPoint = basisFee;
        initialVirtualTokenReserves = 10**27;    // 设置初始虚拟代币储备
        initialVirtualEthReserves = 3*10**21;    // 设置初始虚拟ETH储备
        tokenTotalSupply = 10**27;               // 设置代币总供应量
        mcapLimit = 10**23;                      // 设置市值上限
    }

    // 创建交易池函数
    function createPool(
        address token,     // 代币地址
        uint256 amount     // 代币数量
    ) payable public {
        require(amount > 0, "CreatePool: Larger than Zero");
        require(feeRecipient != address(0), "CreatePool: Non Zero Address");
        require(msg.value >= createFee, "CreatePool: Value Amount");

        // 转移代币到合约
        IERC20(token).transferFrom(msg.sender, address(this), amount);

        // 转移创建费用给接收地址
        payable(feeRecipient).transfer(createFee);

        // 创建代币曲线
        bondingCurve[token] = Token ({
            tokenMint: token,
            virtualTokenReserves: initialVirtualTokenReserves,
            virtualEthReserves: initialVirtualEthReserves,
            realTokenReserves: amount,
            realEthReserves: 0,
            tokenTotalSupply: tokenTotalSupply,
            mcapLimit: mcapLimit,
            complete: false
        });

        emit CreatePool(token, msg.sender);  // 触发创建池子事件
    }

    // 购买代币函数
    function buy(
        address token,      // 代币地址
        uint256 amount,     // 购买数量
        uint256 maxEthCost  // 最大ETH成本
    ) payable public {
        Token storage tokenCurve = bondingCurve[token];
        require(amount > 0, "Should Larger than zero");
        require(tokenCurve.complete == false, "Should Not Completed");

        // 检查剩余代币百分比
        uint256 featureAmount = tokenCurve.realTokenReserves - amount;
        uint256 featurePercentage = featureAmount * 100 / tokenCurve.tokenTotalSupply;
        require(featurePercentage > 20, "Buy Amount Over");

        // 计算ETH成本
        uint256 ethCost = calculateEthCost(tokenCurve, amount);
        require(ethCost <= maxEthCost, "Max Eth Cost");

        // 计算手续费
        uint256 feeAmount = feeBasisPoint * ethCost / 10000;
        uint256 ethAmount = ethCost - feeAmount;

        require(msg.value >= ethCost, "Exceed ETH Cost");

        // 转移手续费
        payable(feeRecipient).transfer(feeAmount);

        // 转移代币
        IERC20(token).transfer(msg.sender, amount);

        // 更新储备
        tokenCurve.realTokenReserves -= amount;
        tokenCurve.virtualTokenReserves -= amount;
        tokenCurve.virtualEthReserves += ethAmount;
        tokenCurve.realEthReserves += ethAmount;

        // 检查是否达到完成条件
        uint256 mcap = tokenCurve.virtualEthReserves * tokenCurve.tokenTotalSupply / tokenCurve.realTokenReserves;
        uint256 percentage = tokenCurve.realTokenReserves * 100 / tokenCurve.tokenTotalSupply;

        if (mcap > tokenCurve.mcapLimit || percentage < 20) {
            tokenCurve.complete = true;
            emit Complete(msg.sender, token, block.timestamp);
        }

        emit Trade(token, ethCost, amount, true, msg.sender, block.timestamp, tokenCurve.virtualEthReserves, tokenCurve.virtualTokenReserves);
    }

    // 出售代币函数
    function sell(
        address token,        // 代币地址
        uint256 amount,       // 出售数量
        uint256 minEthOutput  // 最小ETH输出
    ) public {
        Token storage tokenCurve = bondingCurve[token];
        require(tokenCurve.complete == false, "Should Not Completed");
        require(amount > 0, "Should Larger than zero");

        // 计算ETH数量
        uint256 ethCost = calculateEthCost(tokenCurve, amount);
        if (tokenCurve.realEthReserves < ethCost) {
            ethCost = tokenCurve.realEthReserves;
        }

        require(ethCost >= minEthOutput, "Should Be Larger than Min");

        // 计算手续费
        uint256 feeAmount = feeBasisPoint * ethCost / 10000;

        // 转移ETH
        payable(feeRecipient).transfer(feeAmount);
        payable(msg.sender).transfer(ethCost - feeAmount);

        // 转移代币
        IERC20(token).transferFrom(msg.sender, address(this), amount);

        // 更新储备
        tokenCurve.realTokenReserves += amount;
        tokenCurve.virtualTokenReserves += amount;
        tokenCurve.virtualEthReserves -= ethCost;
        tokenCurve.realEthReserves -= ethCost;

        emit Trade(token, ethCost, amount, false, msg.sender, block.timestamp, tokenCurve.virtualEthReserves, tokenCurve.virtualTokenReserves);
    }

    // 提取资金函数
    function withdraw(
        address token  // 代币地址
    ) public onlyOwner {
        Token storage tokenCurve = bondingCurve[token];
        require(tokenCurve.complete == true, "Should Be Completed");

        // 转移ETH和代币给所有者
        payable(owner).transfer(tokenCurve.realEthReserves);
        IERC20(token).transfer(owner, tokenCurve.realTokenReserves);
    }

    // 计算ETH成本函数
    function calculateEthCost(
        Token memory token,    // 代币信息
        uint256 tokenAmount   // 代币数量
    ) public pure returns (uint256) {
        uint256 virtualTokenReserves = token.virtualTokenReserves;
        uint256 pricePerToken = virtualTokenReserves - tokenAmount;
        uint256 totalLiquidity = token.virtualEthReserves * token.virtualTokenReserves;
        uint256 newEthReserves = totalLiquidity/pricePerToken;
        uint256 ethCost = newEthReserves - token.virtualEthReserves;
        return ethCost;
    }

    // 设置手续费接收地址
    function setFeeRecipient(address newAddr) external onlyOwner {
        require(newAddr != address(0), "Non zero Address");
        feeRecipient = newAddr;
    }
    
    // 设置所有者地址
    function setOwner(address newAddr) external onlyOwner {
        require(newAddr != address(0), "Non zero Address");
        owner = newAddr;
    }

    // 设置初始虚拟储备
    function setInitialVirtualReserves(
        uint256 initToken,  // 初始代币储备
        uint256 initEth    // 初始ETH储备
    ) external onlyOwner {
        require(initEth > 0 && initToken > 0, "Should Larger than zero");
        initialVirtualTokenReserves = initToken;
        initialVirtualEthReserves = initEth;
    }

    // 设置代币总供应量
    function setTotalSupply(uint256 newSupply) external onlyOwner {
        require(newSupply > 0, "Should Larger than zero");
        tokenTotalSupply = newSupply;
    }

    // 设置市值上限
    function setMcapLimit(uint256 newLimit) external onlyOwner {
        require(newLimit > 0, "Should Larger than zero");
        mcapLimit = newLimit;
    }
}

2. TokenFactory.sol

// SPDX-License-Identifier: MIT  // 指定开源协议为MIT
pragma solidity ^0.8.24;         // 指定Solidity编译器版本

import "./Token.sol";  // 导入Token合约

// 定义PumpFun接口
interface IPumpFun {
    // 创建池子函数
    function createPool(
        address token,    // 代币地址
        uint256 amount   // 代币数量
    ) external payable;
    
    // 获取创建费用函数
    function getCreateFee() external view returns(uint256);
}

// TokenFactory合约
contract TokenFactory  {
    uint256 public currentTokenIndex = 0;  // 当前代币索引
    uint256 public immutable INITIAL_AMOUNT = 10**27;  // 初始代币数量

    address public contractAddress;  // PumpFun合约地址
    address public taxAddress = 0x044421aAbF1c584CD594F9C10B0BbC98546CF8bc;  // 税收地址
    
    // 代币结构体
    struct TokenStructure {
        address tokenAddress;  // 代币合约地址
        string tokenName;     // 代币名称
        string tokenSymbol;   // 代币符号
        uint256 totalSupply;  // 总供应量
    }

    TokenStructure[] public tokens;  // 代币数组

    constructor () {}  // 空构造函数

    // 部署ERC20代币函数
    function deployERC20Token (
        string memory name,    // 代币名称
        string memory ticker   // 代币符号
    ) public payable {
        // 创建新代币
        Token token = new Token(name, ticker, INITIAL_AMOUNT);
        
        // 保存代币信息
        tokens.push(
            TokenStructure (
                address(token),
                name,
                ticker,
                INITIAL_AMOUNT
            )
        );

        // 授权PumpFun合约
        token.approve(contractAddress, INITIAL_AMOUNT);
        uint256 balance = IPumpFun(contractAddress).getCreateFee();

        // 创建交易池
        require(msg.value >= balance, "Input Balance Should Be larger");
        IPumpFun(contractAddress).createPool{value: balance}(address(token), INITIAL_AMOUNT);
    }

    // 设置PumpFun合约地址
    function setPoolAddress (address newAddr) public  {
        require(newAddr != address(0), "Non zero Address");
        contractAddress = newAddr;
    } 
}

3. Token.sol

// SPDX-License-Identifier: MIT  // 指定开源协议为MIT
pragma solidity ^0.8.24;         // 指定Solidity编译器版本

// 导入OpenZeppelin的ERC20合约
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

// Token合约,继承自ERC20
contract Token is ERC20 {
    // 构造函数
    constructor(
        string memory tokenName_,     // 代币名称
        string memory tokenSymbol_,   // 代币符号
        uint256 initialSupply        // 初始供应量
    ) ERC20(tokenName_, tokenSymbol_) {
        _mint(msg.sender, initialSupply);  // 铸造初始代币给部署者
    }
}

合约功能说明

这三个合约构成了完整的PumpFun智能合约系统:

  1. PumpFun.sol是核心交易合约,实现了基于虚拟储备的代币交易机制

    • 管理代币交易池
    • 实现买卖功能
    • 处理手续费
    • 控制市场状态
  2. TokenFactory.sol是代币工厂合约,负责创建新的ERC20代币并自动初始化交易池

    • 创建新代币
    • 记录代币信息
    • 自动创建交易池
  3. Token.sol是标准的ERC20代币合约,用于创建新的代币

    • 实现ERC20标准
    • 提供基础代币功能

每个合约都有其特定的功能和职责,通过接口和继承关系相互配合,形成一个完整的代币发行和交易系统。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值