// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {IRelayRegistry} from "./GatedToken.sol";
/// @title GatedMaxToken
/// @notice Combines the two mechanisms: a **buy-gate** (during the blink, buys — transfers out of the pool
/// — only succeed if tx.origin is a whitelisted Relay relayer) AND a **2% max-wallet** anti-whale cap.
/// Sells are always allowed. Pool/launchpad/routers are exempt from the cap.
contract GatedMaxToken is ERC20 {
error NotLaunchpad();
error AlreadyInitialized();
error BuyLocked();
error MaxWalletExceeded();
uint256 public constant TOTAL_SUPPLY = 1_000_000_000e18;
IRelayRegistry public immutable registry;
address public immutable launchpad;
uint256 public immutable maxWallet;
address public pool;
uint64 public windowEnd;
mapping(address => bool) public exempt;
constructor(string memory name_, string memory symbol_, address _launchpad, IRelayRegistry _registry, uint16 maxWalletBps)
ERC20(name_, symbol_)
{
launchpad = _launchpad;
registry = _registry;
maxWallet = (TOTAL_SUPPLY * maxWalletBps) / 10_000;
exempt[_launchpad] = true;
_mint(_launchpad, TOTAL_SUPPLY);
}
/// @notice Launchpad arms the gate (pool + window) and seeds cap exemptions (pool + routers).
function initialize(address _pool, uint64 _windowEnd, address[] calldata exemptions) external {
if (msg.sender != launchpad) revert NotLaunchpad();
if (pool != address(0)) revert AlreadyInitialized();
pool = _pool;
windowEnd = _windowEnd;
exempt[_pool] = true;
for (uint256 i; i < exemptions.length; i++) exempt[exemptions[i]] = true;
}
function setExempt(address a, bool b) external {
if (msg.sender != launchpad) revert NotLaunchpad();
exempt[a] = b;
}
function _update(address from, address to, uint256 value) internal override {
// Buy gate: block buys (out of the pool) during the window unless origin is a whitelisted relayer.
if (pool != address(0) && from == pool && block.timestamp < windowEnd && !registry.isRelayer(tx.origin)) {
revert BuyLocked();
}
super._update(from, to, value);
// Max-wallet cap on non-exempt recipients.
if (to != address(0) && !exempt[to] && balanceOf(to) > maxWallet) revert MaxWalletExceeded();
}
}[
{
"type": "constructor",
"inputs": [
{
"name": "name_",
"type": "string",
"internalType": "string"
},
{
"name": "symbol_",
"type": "string",
"internalType": "string"
},
{
"name": "_launchpad",
"type": "address",
"internalType": "address"
},
{
"name": "_registry",
"type": "address",
"internalType": "contract IRelayRegistry"
},
{
"name": "maxWalletBps",
"type": "uint16",
"internalType": "uint16"
}
],
"stateMutability": "nonpayable"
},
{
"name": "AlreadyInitialized",
"type": "error",
"inputs": []
},
{
"name": "BuyLocked",
"type": "error",
"inputs": []
},
{
"name": "ERC20InsufficientAllowance",
"type": "error",
"inputs": [
{
"name": "spender",
"type": "address",
"internalType": "address"
},
{
"name": "allowance",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "needed",
"type": "uint256",
"internalType": "uint256"
}
]
},
{
"name": "ERC20InsufficientBalance",
"type": "error",
"inputs": [
{
"name": "sender",
"type": "address",
"internalType": "address"
},
{
"name": "balance",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "needed",
"type": "uint256",
"internalType": "uint256"
}
]
},
{
"name": "ERC20InvalidApprover",
"type": "error",
"inputs": [
{
"name": "approver",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "ERC20InvalidReceiver",
"type": "error",
"inputs": [
{
"name": "receiver",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "ERC20InvalidSender",
"type": "error",
"inputs": [
{
"name": "sender",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "ERC20InvalidSpender",
"type": "error",
"inputs": [
{
"name": "spender",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "MaxWalletExceeded",
"type": "error",
"inputs": []
},
{
"name": "NotLaunchpad",
"type": "error",
"inputs": []
},
{
"name": "Approval",
"type": "event",
"inputs": [
{
"name": "owner",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "spender",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "value",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "Transfer",
"type": "event",
"inputs": [
{
"name": "from",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "to",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "value",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "TOTAL_SUPPLY",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "allowance",
"type": "function",
"inputs": [
{
"name": "owner",
"type": "address",
"internalType": "address"
},
{
"name": "spender",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "approve",
"type": "function",
"inputs": [
{
"name": "spender",
"type": "address",
"internalType": "address"
},
{
"name": "value",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "nonpayable"
},
{
"name": "balanceOf",
"type": "function",
"inputs": [
{
"name": "account",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "decimals",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint8",
"internalType": "uint8"
}
],
"stateMutability": "view"
},
{
"name": "exempt",
"type": "function",
"inputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "initialize",
"type": "function",
"inputs": [
{
"name": "_pool",
"type": "address",
"internalType": "address"
},
{
"name": "_windowEnd",
"type": "uint64",
"internalType": "uint64"
},
{
"name": "exemptions",
"type": "address[]",
"internalType": "address[]"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "launchpad",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "maxWallet",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "name",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "string",
"internalType": "string"
}
],
"stateMutability": "view"
},
{
"name": "pool",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "registry",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "contract IRelayRegistry"
}
],
"stateMutability": "view"
},
{
"name": "setExempt",
"type": "function",
"inputs": [
{
"name": "a",
"type": "address",
"internalType": "address"
},
{
"name": "b",
"type": "bool",
"internalType": "bool"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "symbol",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "string",
"internalType": "string"
}
],
"stateMutability": "view"
},
{
"name": "totalSupply",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "transfer",
"type": "function",
"inputs": [
{
"name": "to",
"type": "address",
"internalType": "address"
},
{
"name": "value",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "nonpayable"
},
{
"name": "transferFrom",
"type": "function",
"inputs": [
{
"name": "from",
"type": "address",
"internalType": "address"
},
{
"name": "to",
"type": "address",
"internalType": "address"
},
{
"name": "value",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "nonpayable"
},
{
"name": "windowEnd",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint64",
"internalType": "uint64"
}
],
"stateMutability": "view"
}
]0x6080806040526004361015610012575f80fd5b5f3560e01c90816302669b52146107fa5750806306fdde031461073f578063095ea7b3146106bd57806316f0115b1461069557806318160ddd1461067857806323b872dd14610599578063313ce5671461057e57806370a08231146105475780637b103999146105035780637db1f101146104d9578063902d55a5146104b357806395d89b41146103af5780639fde54f514610334578063a9059cbb14610303578063ca605d89146101ad578063dd62ed3e1461015d578063f1320af2146101205763f8b45b05146100e2575f80fd5b3461011c575f36600319011261011c5760206040517f000000000000000000000000000000000000000000108b2a2c280290940000008152f35b5f80fd5b3461011c57602036600319011261011c576001600160a01b03610141610865565b165f526006602052602060ff60405f2054166040519015158152f35b3461011c57604036600319011261011c57610176610865565b61017e61087b565b6001600160a01b039182165f908152600160209081526040808320949093168252928352819020549051908152f35b3461011c57606036600319011261011c576101c6610865565b60243567ffffffffffffffff8116810361011c576044359067ffffffffffffffff821161011c573660238301121561011c5781600401359267ffffffffffffffff841161011c573660248560051b8501011161011c577f000000000000000000000000f441cc979fa862f2674b9188a7b529cafd3ce2046001600160a01b031633036102f457600554906001600160a01b0382166102e65760018060a01b0316809267ffffffffffffffff60a01b9060a01b169163ffffffff60e01b1617176005555f52600660205260405f20600160ff198254161790555f5b828110156102e4576024600582901b830101356001600160a01b038116919082900361011c576001915f52600660205260405f208260ff19825416179055016102a0565b005b62dc149f60e41b5f5260045ffd5b63ed6fcad960e01b5f5260045ffd5b3461011c57604036600319011261011c5761032961031f610865565b60243590336108c7565b602060405160018152f35b3461011c57604036600319011261011c5761034d610865565b6024359081151580920361011c577f000000000000000000000000f441cc979fa862f2674b9188a7b529cafd3ce2046001600160a01b031633036102f45760018060a01b03165f52600660205260405f209060ff801983541691161790555f80f35b3461011c575f36600319011261011c576040515f6004548060011c906001811680156104a9575b602083108114610495578285529081156104715750600114610413575b61040f8361040381850382610891565b6040519182918261083b565b0390f35b91905060045f527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b915f905b808210610457575090915081016020016104036103f3565b91926001816020925483858801015201910190929161043f565b60ff191660208086019190915291151560051b8401909101915061040390506103f3565b634e487b7160e01b5f52602260045260245ffd5b91607f16916103d6565b3461011c575f36600319011261011c5760206040516b033b2e3c9fd0803ce80000008152f35b3461011c575f36600319011261011c57602067ffffffffffffffff60055460a01c16604051908152f35b3461011c575f36600319011261011c576040517f00000000000000000000000076b7e1fdb7b860e8caa29bd85ef191462854c3566001600160a01b03168152602090f35b3461011c57602036600319011261011c576001600160a01b03610568610865565b165f525f602052602060405f2054604051908152f35b3461011c575f36600319011261011c57602060405160128152f35b3461011c57606036600319011261011c576105b2610865565b6105ba61087b565b6001600160a01b0382165f818152600160209081526040808320338452909152902054909260443592915f1981106105f8575b5061032993506108c7565b83811061065d57841561064a57331561063757610329945f52600160205260405f2060018060a01b0333165f526020528360405f2091039055846105ed565b634a1406b160e11b5f525f60045260245ffd5b63e602df0560e01b5f525f60045260245ffd5b8390637dc7a0d960e11b5f523360045260245260445260645ffd5b3461011c575f36600319011261011c576020600254604051908152f35b3461011c575f36600319011261011c576005546040516001600160a01b039091168152602090f35b3461011c57604036600319011261011c576106d6610865565b60243590331561064a576001600160a01b031690811561063757335f52600160205260405f20825f526020528060405f20556040519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560203392a3602060405160018152f35b3461011c575f36600319011261011c576040515f6003548060011c906001811680156107f0575b6020831081146104955782855290811561047157506001146107925761040f8361040381850382610891565b91905060035f527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b915f905b8082106107d6575090915081016020016104036103f3565b9192600181602092548385880101520191019092916107be565b91607f1691610766565b3461011c575f36600319011261011c577f000000000000000000000000f441cc979fa862f2674b9188a7b529cafd3ce2046001600160a01b03168152602090f35b602060409281835280519182918282860152018484015e5f828201840152601f01601f1916010190565b600435906001600160a01b038216820361011c57565b602435906001600160a01b038216820361011c57565b90601f8019910116810190811067ffffffffffffffff8211176108b357604052565b634e487b7160e01b5f52604160045260245ffd5b6001600160a01b0316908115610acf576001600160a01b0316918215610abc576005546001600160a01b038116801515919082610ab2575b5081610a9b575b50806109fa575b6109eb57815f525f60205260405f20548181106109d25760208284937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9387965f525f84520360405f2055845f525f825260405f20818154019055604051908152a3805f52600660205260ff60405f20541615908161099d575b5061098e57565b632ce93b5960e01b5f5260045ffd5b90505f525f60205260405f20547f000000000000000000000000000000000000000000108b2a2c28029094000000105f610987565b8263391434e360e21b5f5260045260245260445260645ffd5b633d80d6cf60e01b5f5260045ffd5b50604051630a83aaa960e31b81523260048201526020816024817f00000000000000000000000076b7e1fdb7b860e8caa29bd85ef191462854c3566001600160a01b03165afa908115610a90575f91610a55575b501561090d565b90506020813d602011610a88575b81610a7060209383610891565b8101031261011c5751801515810361011c575f610a4e565b3d9150610a63565b6040513d5f823e3d90fd5b67ffffffffffffffff915060a01c1642105f610906565b841491505f6108ff565b63ec442f0560e01b5f525f60045260245ffd5b634b637e8f60e11b5f525f60045260245ffdfea2646970667358221220eef689a95e6f9a3ac33c14f622051afe4afd072c280b5ab33f0ecb68c5925bff64736f6c634300081a0033
| Token | Symbol | Balance | Price | Value |
|---|---|---|---|---|
| no token holdings | ||||
| Transaction Hash | Method | Block | Age | From | To | Amount | Token | ||
|---|---|---|---|---|---|---|---|---|---|
| no token transfers for this address yet | |||||||||
| Type | Age | Block | Details |
|---|---|---|---|
| no cross-chain L1↔L2 transactions for this address | |||
| Txn Hash | Age | Event | Topics / Data |
|---|---|---|---|
| 0x0ea91d…922fe5 | 6 days agoWed, 12 Aug 2026 03:10:03 UTC | Transfer | [0] 0x000000000000…79dc48f9 [1] 0x000000000000…08747f98 data: 0x000000000000000000…40000000 |
| 0x6496c2…ce9577 | 6 days agoWed, 12 Aug 2026 03:09:03 UTC | Transfer | [0] 0x000000000000…cac9819e [1] 0x000000000000…08747f98 data: 0x000000000000000000…e0000000 |
| 0x23f579…a8f69b | 6 days agoWed, 12 Aug 2026 03:08:29 UTC | Transfer | [0] 0x000000000000…ec3b16d6 [1] 0x000000000000…08747f98 data: 0x000000000000000000…e0000003 |
| 0xa86db3…d73649 | 6 days agoWed, 12 Aug 2026 03:08:29 UTC | Approval | [0] 0x000000000000…ec3b16d6 [1] 0x000000000000…262c40dc data: 0x000000000000000000…e0000003 |
| 0x6b44c6…7f1a3a | 6 days agoWed, 12 Aug 2026 03:08:05 UTC | Transfer | [0] 0x000000000000…fd3ce204 [1] 0x000000000000…ac40208f data: 0x000000000000000000…e0000003 |
| 0x6b44c6…7f1a3a | 6 days agoWed, 12 Aug 2026 03:08:05 UTC | Transfer | [0] 0x000000000000…fd3ce204 [1] 0x000000000000…ec3b16d6 data: 0x000000000000000000…e0000003 |
| 0x6b44c6…7f1a3a | 6 days agoWed, 12 Aug 2026 03:08:05 UTC | Transfer | [0] 0x000000000000…08747f98 [1] 0x000000000000…fd3ce204 data: 0x000000000000000000…c0000006 |
| 0xa7e172…9855cf | 6 days agoWed, 12 Aug 2026 03:08:03 UTC | Transfer | [0] 0x000000000000…dd5eebde [1] 0x000000000000…08747f98 data: 0x000000000000000000…40000000 |
| 0x9b04c1…5e8e09 | 6 days agoWed, 12 Aug 2026 03:07:02 UTC | Transfer | [0] 0x000000000000…aa020448 [1] 0x000000000000…08747f98 data: 0x000000000000000000…60000000 |
| 0x091e11…e9737f | 6 days agoWed, 12 Aug 2026 03:06:02 UTC | Transfer | [0] 0x000000000000…79dc48f9 [1] 0x000000000000…08747f98 data: 0x000000000000000000…40000000 |
| 0x1be396…77dde8 | 6 days agoWed, 12 Aug 2026 03:05:02 UTC | Transfer | [0] 0x000000000000…cac9819e [1] 0x000000000000…08747f98 data: 0x000000000000000000…40000000 |
| 0x1934ed…93c513 | 6 days agoWed, 12 Aug 2026 03:04:01 UTC | Transfer | [0] 0x000000000000…dd5eebde [1] 0x000000000000…08747f98 data: 0x000000000000000000…60000000 |
| 0xec051f…79beac | 6 days agoWed, 12 Aug 2026 03:03:01 UTC | Transfer | [0] 0x000000000000…aa020448 [1] 0x000000000000…08747f98 data: 0x000000000000000000…a0000000 |
| 0xa9cfcd…51c5b2 | 6 days agoWed, 12 Aug 2026 03:02:00 UTC | Transfer | [0] 0x000000000000…79dc48f9 [1] 0x000000000000…08747f98 data: 0x000000000000000000…a0000000 |
| 0x67d4c3…2ee9d6 | 6 days agoWed, 12 Aug 2026 03:01:00 UTC | Transfer | [0] 0x000000000000…cac9819e [1] 0x000000000000…08747f98 data: 0x000000000000000000…20000000 |
| 0x9bd840…fcb80c | 6 days agoWed, 12 Aug 2026 03:00:00 UTC | Transfer | [0] 0x000000000000…dd5eebde [1] 0x000000000000…08747f98 data: 0x000000000000000000…40000000 |
| 0x230440…ca76f6 | 6 days agoWed, 12 Aug 2026 02:58:59 UTC | Transfer | [0] 0x000000000000…aa020448 [1] 0x000000000000…08747f98 data: 0x000000000000000000…60000000 |
| 0x491e24…d014b8 | 6 days agoWed, 12 Aug 2026 02:57:59 UTC | Transfer | [0] 0x000000000000…79dc48f9 [1] 0x000000000000…08747f98 data: 0x000000000000000000…e0000000 |
| 0xe625c2…a71c8a | 6 days agoWed, 12 Aug 2026 02:57:58 UTC | Approval | [0] 0x000000000000…79dc48f9 [1] 0x000000000000…959e5cb2 data: 0x000000000000000000…ffffffff |
| 0x005a9d…4d3219 | 6 days agoWed, 12 Aug 2026 02:56:58 UTC | Transfer | [0] 0x000000000000…cac9819e [1] 0x000000000000…08747f98 data: 0x000000000000000000…c0000000 |
| 0x90a6f8…be8a5e | 6 days agoWed, 12 Aug 2026 02:56:56 UTC | Approval | [0] 0x000000000000…cac9819e [1] 0x000000000000…959e5cb2 data: 0x000000000000000000…ffffffff |
| 0xf8da5e…e9cef9 | 6 days agoWed, 12 Aug 2026 02:55:56 UTC | Transfer | [0] 0x000000000000…dd5eebde [1] 0x000000000000…08747f98 data: 0x000000000000000000…a0000000 |
| 0xca654c…7879e5 | 6 days agoWed, 12 Aug 2026 02:55:55 UTC | Approval | [0] 0x000000000000…dd5eebde [1] 0x000000000000…959e5cb2 data: 0x000000000000000000…ffffffff |
| 0x7e393f…16a418 | 6 days agoWed, 12 Aug 2026 02:54:55 UTC | Transfer | [0] 0x000000000000…aa020448 [1] 0x000000000000…08747f98 data: 0x000000000000000000…a0000000 |
| 0x7d18dc…a5504c | 6 days agoWed, 12 Aug 2026 02:54:53 UTC | Approval | [0] 0x000000000000…aa020448 [1] 0x000000000000…959e5cb2 data: 0x000000000000000000…ffffffff |
| Transaction Hash | Method ? | Block | Age | From | To | Amount | Txn Fee ? | ||
|---|---|---|---|---|---|---|---|---|---|
| 0xa86db3…d73649 | Approve | 34,191,331 | 6 days agoWed, 12 Aug 2026 03:08:29 UTC | 0x6a29…16d6 | IN | The Coin | $0.000 ETH | 0.00000194 | |
| 0xe625c2…a71c8a | Approve | 34,185,013 | 6 days agoWed, 12 Aug 2026 02:57:58 UTC | 0x5655…48f9 | IN | The Coin | $0.000 ETH | 0.00000188 | |
| 0x90a6f8…be8a5e | Approve | 34,184,404 | 6 days agoWed, 12 Aug 2026 02:56:56 UTC | 0xef1e…819e | IN | The Coin | $0.000 ETH | 0.00000190 | |
| 0xca654c…7879e5 | Approve | 34,183,741 | 6 days agoWed, 12 Aug 2026 02:55:55 UTC | 0xbd64…ebde | IN | The Coin | $0.000 ETH | 0.00000188 | |
| 0x7d18dc…a5504c | Approve | 34,183,129 | 6 days agoWed, 12 Aug 2026 02:54:53 UTC | 0x9001…0448 | IN | The Coin | $0.000 ETH | 0.00000191 |
| Transaction Hash | Method | Block | Age | From | To | Type | Item | ||
|---|---|---|---|---|---|---|---|---|---|
| no NFT transfers for this address yet | |||||||||
| Block | Age | Parent Transaction Hash | Type | Method | From | To | Value | |
|---|---|---|---|---|---|---|---|---|
| 34,180,102 | 6 days agoWed, 12 Aug 2026 02:49:53 UTC | 0x54e5d3…db0132 | CREATE | launch | 0xf441…e204 | IN | 0x9ae3…3fc4 | 0 ETH |