KaitenToken
0xe94acf4f9401353c9c4bab818468f3d0b233fda3
Verification
Verified
v0.8.28+commit.7893614a
Type
Contract
2,695 bytes
ABI entries
31
15 read · 4 write
License
none
Contract information
- Address
- 0xe94acf4f9401353c9c4bab818468f3d0b233fda3
- Chain
- Robinhood Chain (4663)
- Compiler
- v0.8.28+commit.7893614a
- Optimization
- Enabled
- Creator
- 0x50a4C73931…eaFc0EC3a4
- Creation tx
- 0x72402ad29c…ace17f6060
Token
- Name
- SUSHI
- Symbol
- SUSHI
- Decimals
- 18
- Holders
- 20
- Market
- View token page →
Read contract (15)
MAX_BUY() → uint256
SNIPE_WINDOW() → uint256
TOTAL_SUPPLY() → uint256
allowance(address, address) → uint256
balanceOf(address) → uint256
boughtInWindow(address) → uint256
creator() → address
decimals() → uint8
factory() → address
imageURI() → string
name() → string
pool() → address
snipeEndsAt() → uint256
symbol() → string
totalSupply() → uint256
Events (2)
ApprovalTransfer
ABI
[
{
"inputs": [
{
"internalType": "string",
"name": "name_",
"type": "string"
},
{
"internalType": "string",
"name": "symbol_",
"type": "string"
},
{
"internalType": "string",
"name": "imageURI_",
"type": "string"
},
{
"internalType": "address",
"name": "creator_",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "AlreadyWired",
"type": "error"
},
{
"inputs": [],
"name": "AntiSnipeCap",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"internalType": "uint256",
"name": "allowance",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "needed",
"type": "uint256"
}
],
"name": "ERC20InsufficientAllowance",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "sender",
"type": "address"
},
{
"internalType": "uint256",
"name": "balance",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "needed",
"type": "uint256"
}
],
"name": "ERC20InsufficientBalance",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "approver",
"type": "address"
}
],
"name": "ERC20InvalidApprover",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "receiver",
"type": "address"
}
],
"name": "ERC20InvalidReceiver",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "sender",
"type": "address"
}
],
"name": "ERC20InvalidSender",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "spender",
"type": "address"
}
],
"name": "ERC20InvalidSpender",
"type": "error"
},
{
"inputs": [],
"name": "OnlyFactory",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "Approval",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "from",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "Transfer",
"type": "event"
},
{
"inputs": [],
"name": "MAX_BUY",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "SNIPE_WINDOW",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "TOTAL_SUPPLY",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "address",
"name": "spender",
"type": "address"
}
],
"name": "allowance",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "approve",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "balanceOf",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "buyer",
"type": "address"
}
],
"name": "boughtInWindow",
"outputs": [
{
"internalType": "uint256",
"name": "bought",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "creator",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "decimals",
"outputs": [
{
"internalType": "uint8",
"name": "",
"type": "uint8"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "factory",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "imageURI",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "pool_",
"type": "address"
}
],
"name": "initializeAntiSnipe",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "name",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "pool",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "snipeEndsAt",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "symbol",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "totalSupply",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "transfer",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "from",
"type": "address"
},
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "transferFrom",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
}
]Source code
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
/// @title KaitenToken
/// @notice Fixed-supply ERC20 launched by KaitenFactory. No mint function, no
/// owner. A single anti-snipe rule caps the size of *public buys* (pool
/// -> wallet) for a short window after the pool is created.
/// @dev Anti-snipe is TIMESTAMP-based on purpose: Robinhood Chain is an
/// Arbitrum Orbit L2 where `block.number` is the parent-chain number and
/// is not a reliable local clock. Cap is PER TRANSACTION (0.5% of supply).
contract KaitenToken is ERC20 {
uint256 public constant TOTAL_SUPPLY = 100_000_000e18;
/// @notice max tokens a single non-creator buy may pull from the pool during the window (0.5%).
uint256 public constant MAX_BUY = TOTAL_SUPPLY / 200; // 500,000 tokens
uint256 public constant SNIPE_WINDOW = 5 minutes;
/// @notice the factory that launched this token — exempt, and the only wirer.
address public immutable factory;
/// @notice the creator (launcher) — exempt from the buy cap (incl. initial buy).
address public immutable creator;
string public imageURI;
/// @notice the token's V3 pool; set once by the factory at launch.
address public pool;
/// @notice timestamp at which the anti-snipe cap stops applying.
uint256 public snipeEndsAt;
/// @notice cumulative tokens each recipient has bought FROM the pool during the
/// window. The cap is enforced on this running total, so batching many
/// sub-cap buys into one tx (or one `multicall`) can't slip past it.
mapping(address buyer => uint256 bought) public boughtInWindow;
error OnlyFactory();
error AlreadyWired();
error AntiSnipeCap();
constructor(string memory name_, string memory symbol_, string memory imageURI_, address creator_)
ERC20(name_, symbol_)
{
factory = msg.sender;
creator = creator_;
imageURI = imageURI_;
_mint(msg.sender, TOTAL_SUPPLY); // all supply to the factory; it seeds the LP
}
/// @notice One-time wiring by the factory: record the pool and start the 5-min window.
function initializeAntiSnipe(address pool_) external {
if (msg.sender != factory) revert OnlyFactory();
if (pool != address(0)) revert AlreadyWired();
pool = pool_;
snipeEndsAt = block.timestamp + SNIPE_WINDOW;
}
/// @dev The launch protection. Only *buys* (pool -> recipient) by a non-creator,
/// non-factory wallet, within the window, are capped. Sells (to == pool) and
/// all wallet-to-wallet transfers are unrestricted. Setup transfers (factory
/// seeding the LP) are `to == pool`, so never restricted.
///
/// The cap is on the recipient's CUMULATIVE buys during the window, not on a
/// single transfer: a per-transfer check is trivially defeated by a wrapper
/// contract that loops N sub-cap buys in one tx. Cumulative tracking bounds
/// what any one address can accumulate. (Splitting across many fresh wallets
/// is inherent to any address-based cap and out of scope for this rule.)
function _update(address from, address to, uint256 value) internal override {
address _pool = pool;
if (
_pool != address(0) && from == _pool && to != creator && to != factory
&& block.timestamp < snipeEndsAt
) {
uint256 bought = boughtInWindow[to] + value;
if (bought > MAX_BUY) revert AntiSnipeCap();
boughtInWindow[to] = bought;
}
super._update(from, to, value);
}
}
Chain explorer3868msChain node80ms