LUSG docsLIUM FINANCE Vibenet live · Base Sepolia next Open the app →
Contents
Design

B20, and how LUSG uses it.

B20 is Base's native token standard for stablecoins and real-world assets. A token is created by one call to a factory precompile; there is no token contract to write or audit. It is ERC-20 compatible, with roles, policies, pause, supply caps, memos and, for assets, an ERC-8056 multiplier built in.

Precompiles

PrecompileAddressRole
B20 factory0xB20f000000000000000000000000000000000000createB20(variant, salt, params, initCalls); deterministic addresses starting 0xB200…
Policy Registry0x8453000000000000000000000000000000000002Allowlists, blocklists and combined policies, shared across tokens
Activation Registry0x8453000000000000000000000000000000000001Base's switch for which variants and features are live (all three are on for Vibenet and Base Sepolia)

Upgrade timeline

Beryl2026-06-25 mainnetB20 launches Cobalt2026-09-30 mainnetseize, scheduled multipliercombined policies Denimupcoming, no dateexecutor policy on everytransfer path · NOT policies
Source: the B20 changelog on docs.base.org. Denim carries breaking changes for allowlisted tokens; see open questions.

What LUSG uses

B20 featureLUSG's use
Asset variant, 18 decimalsThe token. 18 decimals keeps the multiplier's rounding at one unit in the last place.
initCalls at creationEvery role, the cap and the policy bindings were set in the single createB20 transaction (0x1f4866c0…be5a →).
Roles (MINT, BURN, PAUSE, UNPAUSE, SEIZE, METADATA, OPERATOR)Split across wallets and contracts; see who holds what.
ERC-8056 UI multiplierCarries the yield. updateUIMultiplier(m, effectiveAt) is scheduled every minute by LusgClock. balanceOf stays raw; balanceOfUI shows dollars.
Policy scopesOne combined policy (KYC allowlist and not sanctions-blocklisted) on TRANSFER_SENDER, TRANSFER_RECEIVER and MINT_RECEIVER.
SEIZE_EXEMPT_POLICYBound to a treasury-only list. It defaults to always-allow, which exempts everyone; see compliance.
Pause by featureTRANSFER, MINT, BURN, SEIZE pause independently. Base Sepolia adds an auto-pause of mint and redeem on a market gap.
Supply cap100,000,000 LUSG on Vibenet (raised from 6,000,000 when the desk opened).
Memos (mintWithMemo, seizeWithMemo)Each mint and seizure carries a reference for reconciliation, for example a custodian settlement ID.

The multiplier, precisely

Creating LUSG

params    = abi.encode((uint8 version = 1, string name, string symbol, address initialAdmin, uint8 decimals = 18))
initCalls = [ grantRole(MINT_ROLE, minter), grantRole(BURN_ROLE, minter),
              grantRole(PAUSE_ROLE, compliance), grantRole(UNPAUSE_ROLE, compliance), grantRole(SEIZE_ROLE, compliance),
              grantRole(METADATA_ROLE, admin), grantRole(OPERATOR_ROLE, clock),
              updateSupplyCap(cap),
              updatePolicy(TRANSFER_SENDER_POLICY, holderPolicy), updatePolicy(TRANSFER_RECEIVER_POLICY, holderPolicy),
              updatePolicy(MINT_RECEIVER_POLICY, holderPolicy), updatePolicy(SEIZE_EXEMPT_POLICY, exemptList) ]
factory.createB20(ASSET = 0, salt, params, initCalls)   // simulate with eth_call first: it returns the address

The token address is deterministic from (variant, sender, salt), so LusgClock was deployed against the predicted address first and received OPERATOR_ROLE inside the same createB20 call.