扭金蛋 GGE · 合约源码
BSC 主网 56 · 已验证(Sourcify exact match,字节码逐字节一致)
1. GGE 代币 0xdb86dAC3Ba63500f37FbB8704187d8b3aB2CF10d
Sourcify 验证记录 · BscScan · 下载源文件
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/* ============================================================
Golden Egg / GGE · BEP20
- 买卖各 1% 税:0.5% → 团队钱包(代币形式,立即到账)
0.5% → 留在本合约,任何人可调用 swapTaxToBnb() 换成 BNB 进分红池
- 分红池就是本合约本身:无 Owner、无提款函数,BNB 只能靠持有人 claim() 领走
- 分红规则:
· 持币 ≥ 10,000,000 GGE 才有资格
· 按持币比例累计(进池那一刻的持仓决定份额,事后加仓不追补)
· 累计可领 ≥ 0.01 BNB 才能领,避免 gas 吃掉收益
============================================================ */
interface IBEP20 {
function balanceOf(address) external view returns (uint256);
function transfer(address, uint256) external returns (bool);
}
interface IPancakeRouter {
function swapExactTokensForETHSupportingFeeOnTransferTokens(
uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline
) external;
}
contract NiuJinDanToken {
string public name = "Golden Egg";
string public symbol = "GGE";
uint8 public constant decimals = 18;
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
/* ---------- 税 ---------- */
uint256 public constant TAX_BPS = 100; // 1%
uint256 public constant TEAM_SHARE_BPS = 50; // 税里一半给团队
address public immutable teamWallet;
address public launchContract; // 打新合约(免税收发奖励用),仅 deployer 可设一次
mapping(address => bool) public taxExempt; // 分发/团队地址免税收发,deployer 设置一次后永久锁定
bool public exemptionsLocked;
IPancakeRouter public immutable router;
address public immutable wbnb;
uint256 public constant SWAP_THRESHOLD = 1_000_000 * 1e18; // 攒够 100 万代币才换 BNB
/* ---------- 分红 ---------- */
uint256 public constant MAG = 1e18;
uint256 public constant MIN_HOLD = 10_000_000 * 1e18; // 门槛 1000 万
uint256 public constant MIN_CLAIM = 0.01 ether; // 最低领取 0.01 BNB
uint256 public accPerShare;
mapping(address => uint256) public lastAcc;
mapping(address => uint256) public pending;
uint256 public totalDividendReceived;
uint256 public totalAllocated; // 已记账给持有人的总额
uint256 public totalClaimed; // 已领走的总额
uint256 public constant TICK_BPS = 500; // 每轮分出合约余额的 5%
address public immutable deployer;
bool private _inSwap;
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
event DividendIn(address indexed from, uint256 amount);
event DividendClaimed(address indexed user, uint256 amount);
event TaxSwapped(uint256 tokens, uint256 bnb);
constructor(
string memory _name,
string memory _symbol,
address _team,
uint256 _supply,
address _holder,
address _router,
address _wbnb
) {
name = _name;
symbol = _symbol;
teamWallet = _team;
totalSupply = _supply;
deployer = msg.sender;
router = IPancakeRouter(_router);
wbnb = _wbnb;
balanceOf[_holder] = _supply;
emit Transfer(address(0), _holder, _supply);
}
/// 打新合约地址只登记一次(登记后永远生效,无法取消)
function setLaunchOnce(address _launch) external {
require(msg.sender == deployer, "not deployer");
require(launchContract == address(0), "locked");
require(_launch != address(0), "zero");
launchContract = _launch;
}
function setExempt(address who, bool on) external {
require(msg.sender == deployer, "not deployer");
require(!exemptionsLocked, "locked");
taxExempt[who] = on;
}
/// 上线后锁死,任何人都不能再改免税名单
function lockExemptions() external {
require(msg.sender == deployer, "not deployer");
exemptionsLocked = true;
}
/* ---------- 分红 ---------- */
receive() external payable {}
/// 每轮把合约 BNB 余额的 5% 记到持有人账上(任何人可调用,没有权限)
/// 未领取的部分不会被重复分配:分配上限 = 余额 - 未领取
function distributeTick() external returns (uint256) {
uint256 bal = address(this).balance;
if (bal == 0) return 0;
uint256 outstanding = totalAllocated - totalClaimed;
uint256 avail = bal > outstanding ? bal - outstanding : 0;
uint256 amount = (bal * TICK_BPS) / 10000;
if (amount > avail) amount = avail;
if (amount == 0) return 0;
_distribute(amount);
return amount;
}
function _eligibleSupply() internal view returns (uint256) {
// 合约自己持有的税代币不参与分红
return totalSupply - balanceOf[address(this)];
}
function _distribute(uint256 amount) internal {
if (amount == 0) return;
uint256 denom = _eligibleSupply();
if (denom == 0) return;
accPerShare += (amount * MAG) / denom;
totalDividendReceived += amount;
totalAllocated += amount;
emit DividendIn(msg.sender, amount);
}
function _settle(address user) internal {
uint256 bal = balanceOf[user];
if (bal == 0) { lastAcc[user] = accPerShare; return; }
uint256 owed = (bal * (accPerShare - lastAcc[user])) / MAG;
if (owed > 0) pending[user] += owed;
lastAcc[user] = accPerShare;
}
/// 持有人自己领 BNB(自付 gas),需持币 ≥ 1000 万、可领 ≥ 0.01 BNB
function claim() external {
_settle(msg.sender);
uint256 amt = pending[msg.sender];
require(balanceOf[msg.sender] >= MIN_HOLD, "hold < 10M");
require(amt >= MIN_CLAIM, "less than 0.01 BNB");
pending[msg.sender] = 0;
totalClaimed += amt;
(bool ok, ) = payable(msg.sender).call{value: amt}("");
require(ok, "bnb fail");
emit DividendClaimed(msg.sender, amt);
}
function claimable(address user) external view returns (uint256) {
uint256 bal = balanceOf[user];
uint256 extra = bal == 0 ? 0 : (bal * (accPerShare - lastAcc[user])) / MAG;
uint256 total = pending[user] + extra;
if (bal < MIN_HOLD || total < MIN_CLAIM) return 0;
return total;
}
/* ---------- 税代币换 BNB(任何人可调用,无需权限) ---------- */
function swapTaxToBnb(uint256 minBnbOut) external {
require(!_inSwap, "busy");
uint256 tokens = balanceOf[address(this)];
require(tokens >= SWAP_THRESHOLD, "below threshold");
_inSwap = true;
_settle(address(this));
balanceOf[address(this)] = 0;
emit Transfer(address(this), address(this), 0);
address[] memory path = new address[](2);
path[0] = address(this);
path[1] = wbnb;
allowance[address(this)][address(router)] = tokens;
uint256 before = address(this).balance;
router.swapExactTokensForETHSupportingFeeOnTransferTokens(
tokens, minBnbOut, path, address(this), block.timestamp
);
uint256 gained = address(this).balance - before;
_inSwap = false;
emit TaxSwapped(tokens, gained);
}
/* ---------- 转账与税 ---------- */
function transfer(address to, uint256 amount) external returns (bool) {
_transfer(msg.sender, to, amount);
return true;
}
function transferFrom(address from, address to, uint256 amount) external returns (bool) {
uint256 a = allowance[from][msg.sender];
require(a >= amount, "allowance");
if (a != type(uint256).max) allowance[from][msg.sender] = a - amount;
_transfer(from, to, amount);
return true;
}
function approve(address spender, uint256 amount) external returns (bool) {
allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function _isExempt(address a) internal view returns (bool) {
return taxExempt[a] || a == address(this) || (launchContract != address(0) && a == launchContract);
}
function _transfer(address from, address to, uint256 amount) internal {
require(balanceOf[from] >= amount, "balance");
_settle(from);
_settle(to);
bool taxed = !_isExempt(from) && !_isExempt(to) && to != address(0);
uint256 tax = taxed ? (amount * TAX_BPS) / 10000 : 0;
uint256 net = amount - tax;
balanceOf[from] -= amount;
balanceOf[to] += net;
if (tax > 0) {
uint256 half = (tax * TEAM_SHARE_BPS) / 100;
balanceOf[teamWallet] += half;
balanceOf[address(this)] += tax - half; // 留在合约,等着换 BNB 进分红池
emit Transfer(from, teamWallet, half);
emit Transfer(from, address(this), tax - half);
}
emit Transfer(from, to, net);
}
}
2. 打新合约 0xAf98b0D9F9Dbe006d9b4cC13f9DBCa923F8756DD
Sourcify 验证记录 · BscScan · 下载源文件
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/* ============================================================
牛金丹 NIUJINDAN · 打新合约
总量 4444 份:1111 免费 + 3333 付费(0.0028 BNB/份)= 9.3324 BNB
每人(每个 .ai 身份)最多 4 份,限时 72 小时
满额后分账:60% 加池(LP 打进黑洞烧掉)/ 20% 团队 / 20% 分红池
未满额:到期后按已付金额退 80%
============================================================ */
interface IBEP20 {
function transfer(address, uint256) external returns (bool);
function transferFrom(address, address, uint256) external returns (bool);
function approve(address, uint256) external returns (bool);
function balanceOf(address) external view returns (uint256);
}
interface IPancakeRouter {
function addLiquidityETH(
address token, uint256 amountTokenDesired, uint256 amountTokenMin,
uint256 amountETHMin, address to, uint256 deadline
) external payable returns (uint256 amountToken, uint256 amountETH, uint256 liquidity);
}
interface IAIIdentity {
function handleOf(address user) external view returns (string memory);
}
contract NiuJinDanLaunch {
// ==== 参数 ====
uint256 public constant TOTAL_SUPPLY = 5000;
uint256 public constant FREE_SUPPLY = 500;
uint256 public constant PRICE = 0.0028 ether;
uint256 public constant MAX_PER_ID = 10;
uint256 public constant DURATION = 72 hours;
uint256 public constant REFUND_BPS = 8000; // 未开盘退 80%
// 稀有度奖励(18 位小数)
uint256 private constant R1 = 50_000_000 * 1e18;
uint256 private constant R2 = 90_000_000 * 1e18;
uint256 private constant R3 = 120_000_000 * 1e18;
uint256 private constant R4 = 150_000_000 * 1e18;
// ==== 状态 ====
address public owner;
IAIIdentity public aiRegistry;
IBEP20 public token;
IPancakeRouter public router;
address public teamWallet;
address public dividendPool;
address public constant DEAD = 0x000000000000000000000000000000000000dEaD;
uint256 public constant POOL_RESERVE = 100_000_000_000 * 1e18; // 100B 固定留给建池
uint256 public startTime;
uint256 public totalMinted;
uint256 public paidMinted;
uint256 public totalBnbPaid;
bool public poolOpened;
bool public liquidityAdded;
mapping(address => uint256) public mintedByAddress;
mapping(address => uint256) public bnbPaid;
mapping(address => bool) public refunded;
event Minted(address indexed user, uint256 tokenId, uint8 rarity, uint256 reward);
event PoolOpened(uint256 bnbPool, uint256 tokensPool, uint256 bnbTeam, uint256 bnbDividend);
event Refunded(address indexed user, uint256 amount);
modifier onlyOwner() { require(msg.sender == owner, "not owner"); _; }
constructor(
address _registry, address _router, address _token,
address _team, address _dividend, address _owner, uint256 _startTime
) {
require(_startTime > block.timestamp, "start must be future");
owner = _owner;
aiRegistry = IAIIdentity(_registry);
router = IPancakeRouter(_router);
token = IBEP20(_token);
teamWallet = _team;
dividendPool = _dividend;
startTime = _startTime;
}
/* ================= 铸造 ================= */
function mint(uint256 amount) external payable {
require(block.timestamp >= startTime, "not started");
require(block.timestamp < startTime + DURATION, "ended");
require(!poolOpened, "pool opened");
require(amount > 0 && amount <= MAX_PER_ID, "bad amount");
require(mintedByAddress[msg.sender] + amount <= MAX_PER_ID, "over per id");
require(totalMinted + amount <= TOTAL_SUPPLY, "sold out");
string memory handle = aiRegistry.handleOf(msg.sender);
require(bytes(handle).length > 0, "no .ai id");
// 免费额度:全站前 1111 份,且每个 .ai 钱包只能免费拿 1 份
uint256 freeLeft = FREE_SUPPLY - (totalMinted - paidMinted);
bool firstFree = (mintedByAddress[msg.sender] == 0 && freeLeft > 0);
uint256 cost;
uint256 newPaid;
for (uint256 i = 0; i < amount; i++) {
if (i == 0 && firstFree) { freeLeft--; }
else { cost += PRICE; newPaid++; }
}
require(msg.value == cost, "wrong bnb");
totalMinted += amount;
paidMinted += newPaid;
mintedByAddress[msg.sender] += amount;
bnbPaid[msg.sender] += cost;
totalBnbPaid += cost;
// 开奖 + 发代币
for (uint256 i = 0; i < amount; i++) {
uint256 id = totalMinted - amount + i;
uint256 seed = uint256(keccak256(abi.encodePacked(
blockhash(block.number - 1), msg.sender, id, totalBnbPaid
))) % 100;
uint8 rarity;
uint256 reward;
if (seed < 60) { rarity = 1; reward = R1; }
else if (seed < 80) { rarity = 2; reward = R2; }
else if (seed < 95) { rarity = 3; reward = R3; }
else { rarity = 4; reward = R4; }
// 玩家额度用完时按剩余量发,绝不超发、绝不 revert
uint256 avail = token.balanceOf(address(this));
uint256 spendable = avail > POOL_RESERVE ? avail - POOL_RESERVE : 0;
if (reward > spendable) reward = spendable;
require(reward > 0, "reward pool empty");
require(token.transfer(msg.sender, reward), "token out");
emit Minted(msg.sender, id, rarity, reward);
}
if (totalMinted == TOTAL_SUPPLY) _openPool();
}
/* ================= 分账 ================= */
function _openPool() internal {
poolOpened = true;
uint256 bal = totalBnbPaid;
uint256 bnbPool = (bal * 60) / 100;
uint256 bnbTeam = (bal * 20) / 100;
uint256 bnbDiv = bal - bnbPool - bnbTeam;
if (bnbTeam > 0) { (bool a, ) = payable(teamWallet).call{value: bnbTeam}(""); require(a, "team fail"); }
if (bnbDiv > 0) { (bool b, ) = payable(dividendPool).call{value: bnbDiv}(""); require(b, "div fail"); }
uint256 tokensForPool = token.balanceOf(address(this));
_addLiquidity(bnbPool, tokensForPool);
emit PoolOpened(bnbPool, tokensForPool, bnbTeam, bnbDiv);
}
/// 加池:只做一次;万一 Pancake 调用失败,任何人都能重试,不需要 Owner
function _addLiquidity(uint256 bnbAmount, uint256 tokenAmount) internal {
if (liquidityAdded || tokenAmount == 0 || bnbAmount == 0) return;
token.approve(address(router), tokenAmount);
// 低层调用:失败不影响开盘状态,留给 retryAddLiquidity 重试
(bool ok, ) = address(router).call{value: bnbAmount}(
abi.encodeWithSignature(
"addLiquidityETH(address,uint256,uint256,uint256,address,uint256)",
address(token), tokenAmount, 0, 0, DEAD, block.timestamp + 600
)
);
if (!ok) return;
liquidityAdded = true;
}
/// 公开重试:开盘后若加池没成功,任何人可以调用
function retryAddLiquidity() external {
require(poolOpened, "not opened");
require(!liquidityAdded, "added");
uint256 bal = totalBnbPaid;
uint256 bnbPool = (bal * 60) / 100;
_addLiquidity(bnbPool, token.balanceOf(address(this)));
}
/// 手动触发(满额前可调用则 revert)
function openPool() external onlyOwner {
require(totalMinted == TOTAL_SUPPLY, "not sold out");
require(!poolOpened, "opened");
_openPool();
}
/* ================= 退款(80%) ================= */
function refund() external {
require(!poolOpened, "pool opened");
require(block.timestamp >= startTime + DURATION, "not ended");
require(!refunded[msg.sender], "done");
uint256 paid = bnbPaid[msg.sender];
require(paid > 0, "nothing");
refunded[msg.sender] = true;
uint256 back = (paid * REFUND_BPS) / 10000;
(bool ok, ) = payable(msg.sender).call{value: back}("");
require(ok, "bnb fail");
emit Refunded(msg.sender, back);
}
/* ================= 只读 ================= */
function freeRemaining() external view returns (uint256) {
return FREE_SUPPLY - (totalMinted - paidMinted);
}
function endTime() external view returns (uint256) { return startTime + DURATION; }
/* ================= 管理 ================= */
function setWallets(address _team, address _dividend) external onlyOwner {
teamWallet = _team; dividendPool = _dividend;
}
function rescueToken(address to, uint256 amt) external onlyOwner {
require(poolOpened || block.timestamp >= startTime + DURATION, "too early");
token.transfer(to, amt);
}
receive() external payable {}
}
编译器 solc 0.8.24+commit.e11b9ed9 · optimizer 200 runs · evmVersion paris