PotatoToken
0x9241589b1cff5440298c64ecffeb142b3dd2cba7
Verification
Verified
v0.8.24+commit.e11b9ed9
Type
Contract
2,408 bytes
ABI entries
28
12 read · 4 write
License
mit
Contract information
- Address
- 0x9241589b1cff5440298c64ecffeb142b3dd2cba7
- Chain
- Robinhood Chain (4663)
- Compiler
- v0.8.24+commit.e11b9ed9
- Optimization
- Enabled
- Creator
- 0xEaC337Ce36…186CFB2CCC
- Creation tx
- 0x6c019607fd…a1def9a072
Token
- Name
- fries
- Symbol
- FRIES
- Decimals
- 18
- Holders
- 32
- Market
- View token page →
Read contract (12)
allowance(address, address) → uint256
antiSnipeDeadlineBlock() → uint256
antiSnipeExempt(address) → bool
balanceOf(address) → uint256
decimals() → uint8
maxWallet() → uint256
name() → string
owner() → address
pad() → address
pool() → address
symbol() → string
totalSupply() → uint256
Events (2)
ApprovalTransfer
ABI
[
{
"inputs": [
{
"internalType": "string",
"name": "name_",
"type": "string"
},
{
"internalType": "string",
"name": "symbol_",
"type": "string"
},
{
"internalType": "uint256",
"name": "supply_",
"type": "uint256"
},
{
"internalType": "address",
"name": "pad_",
"type": "address"
},
{
"internalType": "address",
"name": "positionManager_",
"type": "address"
},
{
"internalType": "address",
"name": "locker_",
"type": "address"
},
{
"internalType": "uint256",
"name": "maxWallet_",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "antiSnipeBlocks_",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"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": "MaxWalletExceeded",
"type": "error"
},
{
"inputs": [],
"name": "OnlyPad",
"type": "error"
},
{
"inputs": [],
"name": "PoolAlreadySet",
"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": [
{
"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": [],
"name": "antiSnipeDeadlineBlock",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "antiSnipeExempt",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"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": [],
"name": "decimals",
"outputs": [
{
"internalType": "uint8",
"name": "",
"type": "uint8"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "maxWallet",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "name",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [],
"name": "pad",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "pool",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "pool_",
"type": "address"
}
],
"name": "setPool",
"outputs": [],
"stateMutability": "nonpayable",
"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.24;
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
/// @title PotatoToken
/// @notice Fixed-supply ERC-20. The entire supply is minted to the launchpad
/// (the deployer) in the constructor. There is no owner, no mint, no
/// pause, no blacklist — nothing a rug could hide in.
///
/// The ONE piece of logic beyond a vanilla ERC-20 is a time-boxed
/// anti-snipe max-wallet cap: for a short window after launch, no
/// non-exempt address may end a transfer holding more than
/// `maxWallet` tokens. This throttles bots from hoovering up the
/// single-sided launch supply in the first few blocks. It is enforced
/// purely on the receiving balance, exempts the launch infrastructure
/// (pad / pool / position manager / locker), and — critically — becomes
/// a complete no-op once `antiSnipeDeadlineBlock` passes, so it can
/// never interfere with normal trading afterwards.
contract PotatoToken is ERC20 {
/// @notice Burn sink for fees. Must be a normal (unspendable) address — OZ
/// ERC20 reverts on transfers to address(0).
address internal constant DEAD = 0x000000000000000000000000000000000000dEaD;
/// @notice The launchpad that deployed this token (holds the full supply at genesis).
address public immutable pad;
/// @notice Max tokens a non-exempt wallet may hold during the anti-snipe window.
uint256 public immutable maxWallet;
/// @notice Last block (inclusive) at which the max-wallet cap is enforced.
uint256 public immutable antiSnipeDeadlineBlock;
/// @notice Addresses exempt from the anti-snipe cap (launch infrastructure).
mapping(address => bool) public antiSnipeExempt;
/// @notice The token's Uniswap V3 pool. Set once by the pad, right after the
/// pool is created (its address isn't known at construction time).
address public pool;
error OnlyPad();
error PoolAlreadySet();
error MaxWalletExceeded();
/// @param pad_ the deployer/launchpad; receives the full supply and is exempt.
/// @param positionManager_ Uniswap NonfungiblePositionManager (exempt).
/// @param locker_ the fee locker that holds the LP NFT (exempt).
/// @param maxWallet_ max non-exempt balance during the anti-snipe window.
/// @param antiSnipeBlocks_ number of blocks AFTER the launch block that stay capped.
constructor(
string memory name_,
string memory symbol_,
uint256 supply_,
address pad_,
address positionManager_,
address locker_,
uint256 maxWallet_,
uint256 antiSnipeBlocks_
) ERC20(name_, symbol_) {
pad = pad_;
maxWallet = maxWallet_;
antiSnipeDeadlineBlock = block.number + antiSnipeBlocks_;
antiSnipeExempt[pad_] = true;
antiSnipeExempt[positionManager_] = true;
antiSnipeExempt[locker_] = true;
// Fee-burn sink: the locker sends the launched-token side of swap fees here,
// which must never trip the max-wallet cap and revert a permissionless
// collect() during the anti-snipe window.
antiSnipeExempt[DEAD] = true;
_mint(pad_, supply_);
}
/// @notice One-time hook for the pad to register the pool as exempt once it
/// exists. The pool must be exempt because it custodies ~the entire
/// supply as single-sided LP.
/// @dev `public virtual` (not external) so subclasses can extend it via
/// `super.setPool` — {PotatoRewardToken} also excludes the pool from
/// holder rewards there. The ABI is identical either way.
function setPool(address pool_) public virtual {
if (msg.sender != pad) revert OnlyPad();
if (pool != address(0)) revert PoolAlreadySet();
pool = pool_;
antiSnipeExempt[pool_] = true;
}
/// @notice Always address(0). PotatoToken has no owner, mint, pause, or
/// blacklist — it is renounced by construction (there was never an owner
/// to renounce). Exposed purely so scanners and DEX tools that detect
/// "renounced" via `owner() == address(0)` recognize it as such.
function owner() external pure returns (address) {
return address(0);
}
/// @dev Enforces the max-wallet cap on the recipient during the anti-snipe
/// window only. After `antiSnipeDeadlineBlock` this is a pure no-op, so
/// transfers behave exactly like a vanilla ERC-20 forever after.
function _update(address from, address to, uint256 value) internal virtual override {
super._update(from, to, value);
if (block.number <= antiSnipeDeadlineBlock && to != address(0) && !antiSnipeExempt[to]) {
if (balanceOf(to) > maxWallet) revert MaxWalletExceeded();
}
}
}
Chain explorer2838msChain node76ms