SMART CONTRACTS
TabBotRouter
TabBotRouter is the companion contract for flows where the user cannot reasonably sign per transaction — social tips triggered by a tweet, or grant payouts from a campaign treasury. It uses a pre-approved allowance plus a trusted executor allowlist instead of a per-call signature.
Trust model in one sentence
Users approve the router as an ERC-20 spender on the stablecoin they want it to be able to move; a wallet on the executors allowlist can then push transfers, capped by the user's allowance and balance.
Constants
BPS_DENOMINATOR = 10_000MAX_FEE_BPS = 500— hard cap of 5%; the owner cannot set the fee higher.
State
IERC20 STABLE— the stablecoin (immutable).address platformTreasuryuint256 platformFeeBps— owner-mutable up to MAX_FEE_BPS.mapping(address => bool) executorsmapping(address => uint256) nonces— strict per-user counter.mapping(bytes32 => bool) usedTweetIds, usedGrants
P2P
function executeP2P(
address from,
address to,
uint256 amount,
uint256 nonce,
string calldata tweetId
) external onlyExecutor nonReentrant;Three layers of dedup: the executor allowlist, the per-user nonce counter (must equal nonces[from]), and the tweet ID keyed on keccak256(bytes(tweetId)).
Grants
function executeGrant(
address sponsor,
address to,
uint256 amount,
string calldata campaignId
) external onlyExecutor nonReentrant;The router pulls from the sponsor wallet (which approved the router) and pays the recipient. One grant per (campaign, recipient) pair, enforced by keccak256(abi.encodePacked(campaignId, to)).
Events
event P2PExecuted(
address indexed from, address indexed to,
uint256 amount, uint256 fee, uint256 nonce, string tweetId
);
event GrantExecuted(
address indexed sponsor, address indexed to,
uint256 amount, uint256 fee, string campaignId
);
event ExecutorAdded(address indexed executor);
event ExecutorRemoved(address indexed executor);
event PlatformFeeUpdated(uint256 oldBps, uint256 newBps);
event PlatformTreasuryUpdated(address indexed oldTreasury, address indexed newTreasury);What the owner can and cannot do
- Can: add or remove executors, rotate the treasury, change the platform fee within the cap.
- Cannot: mint, freeze, claw back, or otherwise touch user funds. The owner has no signature path into a settlement; only executors do, and they're bounded by user allowances.