LRC-20 Fungible Token Standard
This LP retains the Lux Request for Comment 20 standard.
See also: LP-12: C-Chain (Contract Chain) Specification, LP-721: LRC-721 Non-Fungible Token Standard, LP-1155: LRC-1155 Multi-Token Standard
Abstract
The LRC-20 standard defines a fungible token interface for the Lux Network, extending the ERC-20 standard with confidential transfer capabilities using zero-knowledge proofs (zkSNARKs) and support for AI compute token primitives. This enhancement enables privacy-preserving transactions while maintaining compatibility with existing tooling, and introduces specialized support for AI/ML compute resource tokenization.
Activation
| Parameter | Value |
|---|---|
| Flag string | lp20-lrc20-fungible-token |
| Default in code | N/A |
| Deployment branch | N/A |
| Roll-out criteria | N/A |
| Back-off plan | N/A |
LRC-20 is analogous to Ethereum’s well-known ERC-20 fungible token standard. It defines the interface and behavior for fungible tokens on Lux’s platform.
Motivation
A common fungible token interface enables wallet, exchange, and tooling interoperability, simplifies audits, and reduces fragmentation across Lux smart contracts and dApps.
Specification
Core Interface
interface ILRC20 {
// Standard ERC-20 functions
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
// Events
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
Confidential Transfer Extension
interface ILRC20Confidential {
// Confidential balance management
function confidentialBalanceOf(address account) external view returns (bytes32);
function getViewingKey(address account) external view returns (bytes memory);
// Zero-knowledge transfer operations
function confidentialTransfer(
bytes calldata proof,
bytes32 nullifierHash,
bytes32 commitmentHash,
address recipient
) external returns (bool);
// Batch confidential transfers
function batchConfidentialTransfer(
bytes[] calldata proofs,
bytes32[] calldata nullifierHashes,
bytes32[] calldata commitmentHashes,
address[] calldata recipients
) external returns (bool);
// Shield/unshield operations
function shield(uint256 amount, bytes32 commitment) external returns (bool);
function unshield(bytes calldata proof, bytes32 nullifier, uint256 amount) external returns (bool);
// Events
event ConfidentialTransfer(bytes32 indexed nullifierHash, bytes32 indexed commitmentHash);
event Shield(address indexed from, bytes32 commitment, uint256 amount);
event Unshield(address indexed to, bytes32 nullifier, uint256 amount);
}
AI Compute Token Extension
interface ILRC20AICompute {
struct ComputeMetadata {
uint256 flops; // Floating point operations per second
uint256 memoryGb; // Memory in gigabytes
uint256 bandwidthGbps; // Bandwidth in Gbps
string acceleratorType; // "GPU", "TPU", "ASIC", etc.
bytes32 modelHash; // Hash of supported model architectures
}
// AI compute resource management
function registerComputeProvider(ComputeMetadata calldata metadata) external returns (uint256 providerId);
function allocateCompute(uint256 providerId, uint256 amount, uint256 duration) external returns (bytes32 allocationId);
function releaseCompute(bytes32 allocationId) external returns (bool);
// Compute token staking for providers
function stakeComputeTokens(uint256 amount, uint256 providerId) external returns (bool);
function unstakeComputeTokens(uint256 amount, uint256 providerId) external returns (bool);
// Federated learning rewards
function distributeTrainingRewards(
address[] calldata contributors,
uint256[] calldata contributions,
bytes32 modelUpdateHash
) external returns (bool);
// Events
event ComputeAllocated(address indexed user, uint256 providerId, bytes32 allocationId, uint256 amount);
event ComputeReleased(bytes32 indexed allocationId);
event TrainingRewardsDistributed(bytes32 indexed modelUpdateHash, uint256 totalRewards);
}
zkSNARK Proof Structure
struct ConfidentialProof {
uint256[2] a;
uint256[2][2] b;
uint256[2] c;
uint256[8] publicSignals; // [nullifierHash, commitmentHash, recipientHash, ...]
}
Copyright
Copyright and related rights waived via CC0.
Rationale
The design prioritizes clarity, interoperability, and operational simplicity, selecting mechanisms that reduce ambiguity and ease integration across Lux tooling and chains.
Confidential Transfer Rationale
The integration of zkSNARK-based confidential transfers addresses the growing demand for privacy in blockchain transactions while maintaining regulatory compliance through selective disclosure mechanisms. The design follows the approach outlined in Sasson et al. (2014) "Zerocash: Decentralized Anonymous Payments from Bitcoin" with adaptations for account-based models.
Key design decisions:
- Dual Balance System: Maintains separate public and confidential balances to ensure backward compatibility
- Nullifier-Commitment Model: Prevents double-spending while preserving privacy (Ben-Sasson et al., 2014)
- Batch Operations: Reduces gas costs for multiple confidential transfers by amortizing proof verification
- Viewing Keys: Enables authorized parties to audit confidential transactions without compromising privacy
AI Compute Token Rationale
The AI compute extensions recognize tokens as representations of computational resources, following the framework proposed in "Federated Learning: Challenges, Methods, and Future Directions" (Li et al., 2020). This enables:
- Resource Tokenization: Compute resources (GPU hours, TPU cycles) become tradeable assets
- Quality of Service: Metadata ensures compute buyers know resource specifications
- Federated Learning Incentives: Direct token rewards for model training contributions
- Slashing Mechanisms: Staked tokens ensure provider reliability
Backwards Compatibility
This LP is additive. Existing components remain functional; migration can occur incrementally without breaking changes.
Upgradeable Variants
For proxy-based upgradeable contracts:
| Contract | Description |
|---|---|
ERC20Upgradeable.sol | Upgradeable ERC-20 base |
Usage: Initialize in initialize() instead of constructor. See OpenZeppelin Upgrades.
Security Considerations
Standard Security
Follow least‑privilege, validate inputs, and apply cryptographic best practices where applicable to avoid misuse and ambiguity.
Confidential Transfer Security
-
zkSNARK Circuit Security:
- Use trusted setup ceremonies with sufficient entropy (Powers of Tau)
- Implement Groth16 or PLONK proof systems for efficiency
- Regular security audits of circuit implementations
- Reference: Bowe et al. (2018) "Scalable Multi-party Computation for zk-SNARK Parameters"
-
Nullifier Management:
- Maintain global nullifier set to prevent double-spending
- Use Merkle trees for efficient nullifier verification
- Implement rate limiting to prevent nullifier grinding attacks
-
Front-Running Protection:
- Confidential transfers inherently resistant to front-running
- Use commit-reveal schemes for shield/unshield operations
- Time-locked commitments prevent MEV exploitation
AI Compute Security
-
Provider Verification:
- Require proof-of-resource for compute providers
- Implement reputation systems with stake slashing
- Regular attestation of compute availability
-
Model Security:
- Verify model hashes before reward distribution
- Implement differential privacy for federated learning (Dwork & Roth, 2014)
- Secure aggregation protocols for gradient updates
-
Economic Security:
- Minimum staking requirements for providers
- Gradual vesting of compute rewards
- Dispute resolution via on-chain arbitration
Test Cases
Confidential Transfer Tests
describe("LRC20 Confidential Transfers", () => {
it("should shield tokens and update commitments", async () => {
const amount = 100;
const commitment = generateCommitment(amount, randomness);
await token.shield(amount, commitment);
expect(await token.confidentialBalanceOf(user)).to.include(commitment);
});
it("should verify zkSNARK proof for confidential transfer", async () => {
const proof = await generateTransferProof(sender, recipient, amount);
const result = await token.confidentialTransfer(
proof.serialize(),
proof.nullifierHash,
proof.commitmentHash,
recipient
);
expect(result).to.be.true;
});
it("should prevent double-spending with nullifiers", async () => {
const proof = await generateTransferProof(sender, recipient, amount);
await token.confidentialTransfer(proof.serialize(), proof.nullifierHash, proof.commitmentHash, recipient);
await expect(
token.confidentialTransfer(proof.serialize(), proof.nullifierHash, proof.commitmentHash, recipient)
).to.be.revertedWith("Nullifier already used");
});
});
AI Compute Tests
describe("LRC20 AI Compute", () => {
it("should register compute provider with metadata", async () => {
const metadata = {
flops: ethers.parseUnits("100", 12), // 100 TFLOPS
memoryGb: 80,
bandwidthGbps: 100,
acceleratorType: "GPU",
modelHash: keccak256("transformer-large")
};
const providerId = await token.registerComputeProvider(metadata);
expect(providerId).to.be.gt(0);
});
it("should distribute federated learning rewards", async () => {
const contributors = [addr1, addr2, addr3];
const contributions = [30, 50, 20]; // Percentage contributions
const modelUpdateHash = keccak256("model-v2");
await token.distributeTrainingRewards(contributors, contributions, modelUpdateHash);
for(let i = 0; i < contributors.length; i++) {
const balance = await token.balanceOf(contributors[i]);
expect(balance).to.be.gt(0);
}
});
});
Reference Implementation
A reference implementation is available at: https://github.com/luxfi/lrc20-enhanced
Key components:
contracts/LRC20Confidential.sol: zkSNARK-based privacy implementationcontracts/LRC20AICompute.sol: AI compute token extensionscircuits/transfer.circom: Circom circuits for confidential transfersscripts/trusted-setup.js: Powers of Tau ceremony implementation
Implementation
Standard Library Location
- Local Implementation:
standard/src/ - LRC-20 Base:
standard/src/ERC20.sol(reference) - GitHub Repository: https://github.com/luxfi/standard
Confidential Transfer Implementation
- Source Files:
- Privacy extensions:
standard/src/(LRC20Confidential-derived) - zkSNARK integration: Reference implementation directory
- Test cases:
standard/test/
- Privacy extensions:
AI Compute Token Extensions
- Compute Provider Registry: Available in standard library
- Federated Learning Rewards: Staking and reward logic
- Quality of Service: Provider metadata validation
Testing Infrastructure
cd standard
forge test # Run all LRC-20 tests
forge test --match "Confidential" # Test privacy features
forge test --match "AICompute" # Test AI extensions
Integration with C-Chain
- Deployment: C-Chain EVM compatibility via LP-26
- Address: Custom deployment address on respective chains
- Interoperability: Cross-chain token transfers via LP-21
References
- Ben-Sasson, E., et al. (2014). "Zerocash: Decentralized Anonymous Payments from Bitcoin." IEEE Symposium on Security and Privacy.
- Bowe, S., et al. (2018). "Scalable Multi-party Computation for zk-SNARK Parameters." IACR Cryptology ePrint Archive.
- Groth, J. (2016). "On the Size of Pairing-Based Non-Interactive Arguments." EUROCRYPT.
- Li, T., et al. (2020). "Federated Learning: Challenges, Methods, and Future Directions." IEEE Signal Processing Magazine.
- Dwork, C., & Roth, A. (2014). "The Algorithmic Foundations of Differential Privacy." Foundations and Trends in Theoretical Computer Science.
- Boneh, D., et al. (2020). "Bulletproofs: Short Proofs for Confidential Transactions and More." IEEE Symposium on Security and Privacy.