Token Standard
A standardized smart contract interface for advanced token functionality on Core Blockchain (CBC), supporting operators, hooks, and improved composability over CBC-20.
Abstract
This standard defines an advanced token interface for Core Blockchain (CBC), introducing operator-based transfers, send/receive hooks, and improved composability compared to CBC-20. CBC-777 enables more flexible and secure token interactions, supporting use cases such as escrow, atomic swaps, and on-chain services.
Motivation
CBC-20 tokens are widely used but have limitations, such as lack of hooks for sending/receiving tokens and inflexible approval mechanisms. CBC-777 addresses these issues by introducing operators (trusted accounts that can send tokens on behalf of others) and hooks (functions called on send/receive), enabling safer and more powerful token workflows for DeFi, gaming, and enterprise applications.
Specification
Interface
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface ICBC777 /* is ICBC165 */ {
// --- Events ---
event Sent(address indexed operator, address indexed from, address indexed to, uint256 amount, bytes data, bytes operatorData);
event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);
event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);
event AuthorizedOperator(address indexed operator, address indexed tokenHolder);
event RevokedOperator(address indexed operator, address indexed tokenHolder);
// --- Core Functions ---
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function granularity() external view returns (uint256);
function totalSupply() external view returns (uint256);
function balanceOf(address owner) external view returns (uint256);
function send(address to, uint256 amount, bytes calldata data) external;
function burn(uint256 amount, bytes calldata data) external;
function isOperatorFor(address operator, address tokenHolder) external view returns (bool);
function authorizeOperator(address operator) external;
function revokeOperator(address operator) external;
function operatorSend(address from, address to, uint256 amount, bytes calldata data, bytes calldata operatorData) external;
function operatorBurn(address from, uint256 amount, bytes calldata data, bytes calldata operatorData) external;
function defaultOperators() external view returns (address[] memory);
}
Send and Receive Hooks
Contracts can register as senders or recipients to receive notifications via hooks. Hooks are discovered using CBC-165 interface detection.
interface ICBC777Sender {
function tokensToSend(address operator, address from, address to, uint256 amount, bytes calldata data, bytes calldata operatorData) external;
}
interface ICBC777Recipient {
function tokensReceived(address operator, address from, address to, uint256 amount, bytes calldata data, bytes calldata operatorData) external;
}
Hook Registration and Discovery
- Contracts MUST implement CBC-165 and return
true
for the interface IDs ofICBC777Sender
and/orICBC777Recipient
as appropriate. - If a hook is not registered, the token contract MUST proceed without calling it.
- If a hook is registered but reverts, the token transfer MUST revert.
- If a contract does not implement the hook, tokens may be locked; implementers should take care to avoid accidental lockup.
Default Operators
- CBC-777 supports a list of default operators (e.g., exchanges, custodians) that are operators for all token holders unless explicitly revoked by a holder.
- The
defaultOperators()
function returns the list of default operator addresses. - Token holders can revoke or re-authorize default operators at any time.
Method Behaviors
- The
granularity
function MUST return the smallest transferable unit (usually 1). All token amounts MUST be a multiple of granularity. - The
send
andoperatorSend
functions MUST call thetokensToSend
andtokensReceived
hooks if registered. - Operators MAY be authorized or revoked by token holders at any time. Default operators can be revoked per holder.
- Minting and burning MUST emit the appropriate events.
- Contracts implementing CBC-777 MUST implement CBC-165
supportsInterface
. - For CBC-20 compatibility, contracts MAY emit
Transfer
andApproval
events as appropriate.
Operator Authorization and Revocation
- Any address can be authorized as an operator by a token holder using
authorizeOperator
. - Operators can be revoked at any time using
revokeOperator
. - The
isOperatorFor
function returnstrue
if the operator is authorized for the token holder, either directly or as a default operator (unless revoked). - Operators can call
operatorSend
andoperatorBurn
on behalf of the token holder.
Granularity and Decimals
granularity()
defines the smallest transferable unit. For most tokens, this MUST be 1.- CBC-777 does not require a
decimals()
function, but it MAY be implemented for compatibility with CBC-20.
Events
- All token movements (send, mint, burn) MUST emit the appropriate events (
Sent
,Minted
,Burned
). - Operator authorization and revocation MUST emit
AuthorizedOperator
andRevokedOperator
events. - For CBC-20 compatibility,
Transfer
andApproval
events MAY be emitted.
Reference Implementation
A reference implementation can be provided upon request, following the CBC-777 interface and best practices for hooks and operator management.
Rationale
CBC-777 improves on CBC-20 by enabling advanced token flows, such as escrow, atomic swaps, and on-chain services, through hooks and operator permissions. Default operators simplify integration with custodians and exchanges. This design increases security and composability for modern dApps.
Backward Compatibility
CBC-777 is backward compatible with CBC-20. Implementers MAY include CBC-20 functions and events for compatibility with existing wallets and dApps. Dual implementation is recommended for maximum interoperability.
Security Considerations
- Implementers must ensure hooks are only called on contracts that register for them (using CBC-165).
- Operator permissions should be managed carefully to prevent unauthorized transfers. Default operators should be chosen with care.
- Granularity should be set to prevent rounding errors and ensure divisibility is as intended.
- Upgradability and access control best practices should be followed.
- Reentrancy: Hooks can call back into the token contract. Use reentrancy guards where appropriate.
- Accidental token lockup: If tokens are sent to a contract that does not implement
tokensReceived
, they may be locked. User interfaces should warn users. - Operator abuse: Token holders should be able to easily view and manage their operators.
Copyright
Copyright and related rights waived via CC0.