B20-compatible soul-bound gitStock contracts for Base Beryl. Native token standard implementation of RWA stock tokens on Base L2.
gitStock B20 lets GitHub contributors hold tokenized stocks inside their Gitbank vault, anchored to Base's native B20 token standard (Base Beryl upgrade).
Each B20 gitStock token is:
- Soul-bound: transfer policy set to disabled, cannot be moved P2P
- On-chain memo: every mint and burn records GitHub metadata on-chain
- Role-based: MINTER_ROLE, BURNER_ROLE, PAUSER_ROLE (OpenZeppelin AccessControl)
- Compliance-ready: burnBlocked() for RWA regulatory requirements
- Pausable: emergency stop via PAUSER_ROLE
| Feature | ERC-20 (v1) | B20 (v2 - Beryl) |
|---|---|---|
| Token standard | ERC-20 | B20 Asset variant |
| Transfer policy | Hard revert | Policy-based (B20 native) |
| Mint/burn memo | No | Yes (on-chain audit trail) |
| Access control | Single minter addr | MINTER/BURNER/PAUSER roles |
| Compliance burn | No | burnBlocked() function |
| Gas cost | Standard EVM | ~50% cheaper (precompile) |
Both standards run in parallel. ERC-20 v1 contracts on mainnet remain live.
| Contract | Description |
|---|---|
| GitStockTokenB20 | Soul-bound B20-compatible ERC-20, per ticker |
| GitStockFactoryB20 | Deploys and manages GitStockTokenB20 per ticker |
| IB20Asset | Interface defining the Base Beryl B20 Asset variant spec |
Factory: deployStock(name, symbol, ticker, decimals) — onlyAdmin
Mint: mintWithMemo(ticker, to, amount, memo) — onlyMinter
Burn: burnWithMemo(ticker, from, amount, memo) — onlyMinter
Memo encoding: abi.encode(githubUserId string, issueId uint256, ticker string, usdcSpent uint256)
This repo currently deploys Solidity contracts that implement the IB20Asset interface.
When Base publishes the B20 precompile deployer address, GitStockFactoryB20.deployStock()
will call IB20Deployer(B20_DEPLOYER).deployAsset(config) instead.
All external callers (relayer, webhook, scripts) require zero changes on upgrade.
cp .env.example .env
# fill in DEPLOYER_PRIVATE_KEY, RELAYER_SIGNING_KEY, BASE_SEPOLIA_RPC_URL
node scripts/beryl-deploy.cjsDeployed addresses saved to contracts/deployments-beryl.json.
npx hardhat test test/GitStockB20.ts12 tests: deploy, mintWithMemo + event, burnWithMemo + event, soul-bound transfer revert, soul-bound approve revert, access control, burnBlocked, pause, duplicate ticker revert, tickers list, multiple stocks independent.
DEPLOYER_PRIVATE_KEY= # 0x-prefixed deployer key
RELAYER_SIGNING_KEY= # 0x-prefixed relayer key (minter address derived from this)
BASE_SEPOLIA_RPC_URL= # Base Sepolia / Beryl Sepolia RPC endpoint
BASE_MAINNET_RPC_URL= # Base mainnet RPC endpoint
BASESCAN_API_KEY= # For Basescan contract verificationApache 2.0. See LICENSE.