Development of Social Token System
Social tokens are one of the few Web3 products where blockchain's technical capabilities found truly organic use case. A content creator, influencer, DAO or community launches a token that represents access, participation and economic connection to that creator. The problem with most existing implementations — the token exists in isolation: you can't "use" it outside one app, economics are weak (why hold?), distribution mechanisms don't create truly aligned community. A proper social token system solves these three problems comprehensively.
Typology of Social Tokens
Before designing, define the type:
Creator tokens — personal token of specific person (musician, artist, Twitch streamer). Holders get access to exclusive content, backstage, early access. Examples: Rally.io, Roll, Friends With Benefits ($FWB).
Community/DAO tokens — community token with governance rights. Holders vote on decisions, share treasury, manage project direction.
Social graph tokens — tokens reflecting reputation and social connections (Lens Protocol, Farcaster). Soulbound or partially transferable.
Access tokens — simplest form: token as key to closed chat, platform, Discord server. Technically NFT or ERC-20 with minimum balance.
Token Bonding Curves: Creator Token Economics
Fixed price doesn't work for creator tokens — no mechanism for automatic price discovery and liquidity. Bonding curve — a mathematical function determining token price based on current supply:
Price = f(Supply)
When buying, tokens mint, reserve (ETH/USDC) refills. When selling — tokens burn, reserve is returned. No orderbook, no counterparty.
Linear Bonding Curve
contract LinearBondingCurve {
// Price = slope * supply + initialPrice
uint256 public slope; // in wei per token^2 / 1e18
uint256 public initialPrice; // starting price
uint256 public totalSupply;
uint256 public reserveBalance;
IERC20 public reserveToken; // USDC
IERC20 public bondedToken;
function getBuyPrice(uint256 tokenAmount) public view returns (uint256) {
// integral from currentSupply to (currentSupply + tokenAmount)
// area under linear curve = slope/2 * (s1^2 - s0^2) + initialPrice * (s1 - s0)
uint256 s0 = totalSupply;
uint256 s1 = totalSupply + tokenAmount;
uint256 area = (slope * (s1 * s1 - s0 * s0)) / (2 * 1e18);
uint256 baseCost = initialPrice * tokenAmount / 1e18;
return area + baseCost;
}
function getSellReturn(uint256 tokenAmount) public view returns (uint256) {
require(tokenAmount <= totalSupply, "Not enough supply");
uint256 s0 = totalSupply - tokenAmount;
uint256 s1 = totalSupply;
uint256 area = (slope * (s1 * s1 - s0 * s0)) / (2 * 1e18);
uint256 baseCost = initialPrice * tokenAmount / 1e18;
// spread: selling returns slightly less than buying (creator fee)
uint256 gross = area + baseCost;
return gross * (10000 - creatorFee) / 10000;
}
function buy(uint256 tokenAmount, uint256 maxCost) external nonReentrant {
uint256 cost = getBuyPrice(tokenAmount);
require(cost <= maxCost, "Slippage exceeded");
reserveToken.safeTransferFrom(msg.sender, address(this), cost);
reserveBalance += cost;
totalSupply += tokenAmount;
// mint tokens to buyer
IMintable(address(bondedToken)).mint(msg.sender, tokenAmount);
// creator fee from spread goes to creator
uint256 creatorShare = cost * creatorFeeRate / 10000;
reserveToken.safeTransfer(creatorAddress, creatorShare);
emit TokensBought(msg.sender, tokenAmount, cost);
}
}
Sigmoid Curve for More Stable Growth
Linear curve creates excessive price growth. Sigmoid (S-shaped) curve better reflects real adoption dynamics: slow growth at start, fast in middle, plateau at saturation:
Price = maxPrice / (1 + e^(-k * (supply - inflection)))
Implementing sigmoid on-chain requires approximation — full exp() is gas-expensive. Piecewise-linear approximations or precomputed lookup tables are used.
Access and Gating Mechanisms
Token should actually unlock something. Typical mechanisms:
On-chain gating via balances
// Frontend check (not secure for critical content)
const hasAccess = useToken({
address: creatorTokenAddress,
functionName: "balanceOf",
args: [userAddress],
});
return hasAccess >= MINIMUM_BALANCE;
// Backend check (secure version)
app.middleware("/exclusive/*", async (req, res, next) => {
const { address, signature, message } = req.headers;
// verify signature (SIWE — Sign In With Ethereum)
const session = await verifySiwe(message, signature, address);
if (!session.valid) return res.status(401).json({ error: "Invalid signature" });
// check token balance on-chain
const balance = await provider.readContract({
address: creatorTokenAddress,
abi: erc20Abi,
functionName: "balanceOf",
args: [session.address],
});
if (balance < MINIMUM_BALANCE) {
return res.status(403).json({ error: "Insufficient token balance" });
}
next();
});
NFT-based memberships (ERC-1155)
Instead of quantity of fungible tokens — specific NFTs for different membership levels:
contract CreatorMembership is ERC1155 {
uint256 public constant BRONZE = 1;
uint256 public constant SILVER = 2;
uint256 public constant GOLD = 3;
uint256 public constant LIFETIME = 4;
mapping(uint256 => uint256) public membershipPrice; // in USDC
mapping(uint256 => uint256) public membershipDuration; // in seconds
mapping(address => mapping(uint256 => uint256)) public membershipExpiry;
function purchaseMembership(uint256 tierId) external {
require(membershipPrice[tierId] > 0, "Invalid tier");
usdc.safeTransferFrom(msg.sender, creatorAddress, membershipPrice[tierId]);
uint256 expiry;
if (tierId == LIFETIME) {
expiry = type(uint256).max;
} else {
expiry = block.timestamp + membershipDuration[tierId];
}
membershipExpiry[msg.sender][tierId] = expiry;
_mint(msg.sender, tierId, 1, "");
}
function hasActiveMembership(address user, uint256 tierId) public view returns (bool) {
return membershipExpiry[user][tierId] > block.timestamp;
}
// memberships non-transferable by default
function _beforeTokenTransfer(...) internal override {
require(from == address(0) || to == address(0), "Membership non-transferable");
}
}
Integration with Social Protocols
Modern social token system shouldn't exist in isolation. Integration with open social protocols:
Lens Protocol (Polygon) — on-chain social graph. Follow NFT, publication NFT, collect NFT. Creator token tied to Lens profile: only token holders can comment or get discount at collect.
Farcaster (Base/Optimism) — decentralized social network with on-chain identification. Farcaster Frames allow embedding interactive components directly in posts — including buying creator tokens without leaving app.
// Farcaster Frame for buying creator tokens
app.post("/frames/buy-token", async (req, res) => {
const { trustedData } = req.body;
const { fid, buttonIndex, inputText } = await validateFrameMessage(trustedData);
const amount = parseInt(inputText) || 1;
const price = await getCurvePrice(amount);
// format transaction calldata for direct mint
const txData = encodeFunctionData({
abi: bondingCurveAbi,
functionName: "buy",
args: [BigInt(amount * 1e18), BigInt(price * 1.01 * 1e6)], // 1% slippage
});
return res.json({
type: "tx",
chainId: "eip155:8453", // Base
method: "eth_sendTransaction",
params: {
abi: bondingCurveAbi,
to: bondingCurveAddress,
data: txData,
}
});
});
Tokenomics and Retention Mechanics
Technically correct system doesn't guarantee adoption. Important tokenomic mechanics:
Revenue sharing: percentage of creator's income (merchandise, streaming, consulting) automatically distributed to holders via on-chain split contract (0xSplits). This creates real incentive to hold token.
Exclusive access layering: not binary access (yes/no), but gradation: 1 token = basic access, 10 tokens = priority chat, 100 tokens = advisory board access. Creates incentive to accumulate.
Governance over creator decisions: holders vote on some creator decisions — track selection, next course topic, DAO direction. Creates engaged community, not just investors.
Soul-bound reputation layer over transferable tokens: some achievements (first 100 holders, participation in specific vote) issued as non-transferable badges. Transferable token reflects economic interest, soulbound badge — participation history.
Platform Infrastructure
| Component | Technologies |
|---|---|
| Token contracts | ERC-20 + bonding curve / ERC-1155 memberships |
| Social layer | Lens Protocol integration / custom social graph |
| Content gating | SIWE auth + on-chain balance check |
| Fan dashboard | Next.js + wagmi, real-time via Alchemy webhooks |
| Creator dashboard | Sales analytics, benefits management, revenue split |
| Notifications | Push Protocol (EPNS) — web3-native notifications |
| Payments | Stablecoin (USDC) + native token for minimize volatility |
Push Protocol (formerly EPNS) — important detail: it allows sending notifications to wallet addresses via web3-native channel. Important for notifications about new content, votes, income distribution without email.







