Contract Metadata Standard
WIA-FIN-007 Phase 1 defines comprehensive metadata schemas that describe smart contracts in a machine-readable format, enabling better tooling, security analysis, and ecosystem integration.
Metadata JSON Schema
{
"$schema": "https://wia.org/schemas/contract-metadata/v1.0.0",
"wiaVersion": "1.0.0",
"contractInfo": {
"name": "SecureToken",
"type": "ERC20",
"version": "1.2.3",
"description": "A secure, audited ERC-20 token implementation",
"author": "Your Organization",
"license": "MIT",
"repository": "https://github.com/org/secure-token",
"documentation": "https://docs.example.com/secure-token"
},
"security": {
"audited": true,
"auditor": "CertiK",
"auditDate": "2025-01-15",
"auditReport": "https://certik.com/audit/report-hash",
"vulnerabilities": [],
"securityLevel": "high",
"reentrancyGuard": true,
"overflowProtection": true,
"accessControl": {
"type": "Ownable2Step",
"roles": ["OWNER", "MINTER", "PAUSER"]
},
"pausable": true,
"timelocked": false
},
"deployment": {
"networks": [
{
"chainId": 1,
"name": "ethereum",
"address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"deployedAt": "2025-01-20T10:00:00Z",
"blockNumber": 18500000,
"transactionHash": "0x..."
},
{
"chainId": 137,
"name": "polygon",
"address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"deployedAt": "2025-01-20T10:05:00Z"
}
],
"upgradeable": true,
"upgradePattern": "TransparentProxy",
"proxyAddress": "0x...",
"implementationAddress": "0x...",
"adminAddress": "0x...",
"initializer": "initialize",
"constructorArgs": []
},
"features": {
"mintable": true,
"burnable": true,
"pausable": true,
"snapshot": false,
"permit": true,
"flashMint": false,
"voting": false
},
"gasOptimization": {
"level": "high",
"techniques": ["storage-packing", "cached-reads", "short-circuit"],
"estimatedDeployGas": 1500000,
"estimatedTransferGas": 65000,
"benchmarks": {
"transfer": { "min": 50000, "avg": 65000, "max": 75000 },
"approve": { "min": 45000, "avg": 46000, "max": 47000 }
}
},
"standards": {
"implements": ["ERC20", "ERC2612", "WIA-FIN-007"],
"compatible": ["ERC20Metadata", "ERC165"]
},
"dependencies": {
"@openzeppelin/contracts": "5.0.0",
"@wia/contracts": "1.0.0"
}
}
ABI Extensions
WIA extends the standard Ethereum ABI with additional metadata for enhanced security and tooling support:
{
"type": "function",
"name": "transfer",
"inputs": [
{
"name": "to",
"type": "address",
"internalType": "address",
"wiaValidation": {
"notZeroAddress": true,
"notContractAddress": false,
"checkBlacklist": true
},
"description": "Recipient address"
},
{
"name": "amount",
"type": "uint256",
"internalType": "uint256",
"wiaValidation": {
"minValue": "0",
"maxValue": "type(uint256).max",
"checkBalance": true
},
"description": "Amount of tokens to transfer"
}
],
"outputs": [
{
"name": "success",
"type": "bool",
"description": "True if transfer succeeded"
}
],
"stateMutability": "nonpayable",
"wiaExtensions": {
"accessControl": "public",
"gasEstimate": { "min": 50000, "avg": 65000, "max": 75000 },
"reentrancyProtected": true,
"pausable": true,
"emitsEvents": ["Transfer"],
"modifiers": ["whenNotPaused", "nonReentrant"],
"securityChecks": ["balance", "allowance", "blacklist"],
"errorCodes": {
"InsufficientBalance": "ERC20: transfer amount exceeds balance",
"InvalidRecipient": "ERC20: transfer to the zero address"
},
"documentation": {
"notice": "Transfers tokens from caller to recipient",
"dev": "Implements CEI pattern and emits Transfer event",
"param": {
"to": "Must not be zero address",
"amount": "Must not exceed sender balance"
},
"return": "success Boolean indicating transfer success"
},
"examples": [
{
"language": "javascript",
"code": "await token.transfer('0x...', ethers.utils.parseEther('100'))"
}
]
}
}
Storage Layout Optimization
Slot Packing Strategy
Efficient storage packing reduces gas costs significantly. WIA-FIN-007 defines standardized patterns:
// INEFFICIENT: Uses 5 storage slots
contract InefficientStorage {
bool public paused; // Slot 0 (1 byte, wastes 31 bytes)
address public owner; // Slot 1 (20 bytes, wastes 12 bytes)
uint256 public counter; // Slot 2 (32 bytes)
bool public initialized; // Slot 3 (1 byte, wastes 31 bytes)
uint8 public decimals; // Slot 4 (1 byte, wastes 31 bytes)
}
// EFFICIENT: Uses 2 storage slots (saves 60,000 gas on deployment!)
contract EfficientStorage {
// Slot 0: Pack small types together
bool public paused; // 1 byte
bool public initialized; // 1 byte
uint8 public decimals; // 1 byte
address public owner; // 20 bytes
// Total: 23 bytes in Slot 0
// Slot 1: uint256 gets its own slot
uint256 public counter; // 32 bytes
}
// WIA-FIN-007 Standard Layout
contract WIAStandardStorage {
// ==== SLOT 0-9: Packed Configuration ====
address private _owner; // Slot 0 (20 bytes)
bool private _paused; // Slot 0 (1 byte)
bool private _initialized; // Slot 0 (1 byte)
uint8 private _decimals; // Slot 0 (1 byte)
uint8 private _version; // Slot 0 (1 byte)
// 8 bytes remaining in Slot 0
// ==== SLOT 10-49: Core State ====
uint256 private _totalSupply; // Slot 10
mapping(address => uint256) private _balances; // Slot 11
mapping(address => mapping(address => uint256)) private _allowances; // Slot 12
// ==== SLOT 50-99: Feature State ====
mapping(address => bool) private _blacklist; // Slot 50
mapping(bytes32 => bool) private _usedNonces; // Slot 51
// ==== SLOT 100-199: Reserved for Upgrades ====
uint256[100] private __gap;
// ==== SLOT 200+: Extension Data ====
}
Bytecode Standards
Compiler Configuration
WIA-FIN-007 recommends specific compiler settings for security and optimization:
{
"solidity": {
"version": "0.8.20",
"settings": {
"optimizer": {
"enabled": true,
"runs": 200,
"details": {
"yul": true,
"yulDetails": {
"stackAllocation": true,
"optimizerSteps": "dhfoDgvulfnTUtnIf"
}
}
},
"viaIR": true,
"evmVersion": "shanghai",
"metadata": {
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"abi",
"evm.bytecode",
"evm.deployedBytecode",
"evm.methodIdentifiers",
"metadata",
"storageLayout"
]
}
}
}
},
"wiaValidation": {
"maxBytecodeSize": 24576,
"enforceImmutables": true,
"requireNatSpec": true
}
}
Event Data Structures
Standard Event Formats
// WIA Standard Events
event WIAContractDeployed(
address indexed contractAddress,
string contractType,
string version,
uint256 timestamp
);
event WIAContractUpgraded(
address indexed proxy,
address indexed oldImplementation,
address indexed newImplementation,
string version,
uint256 timestamp
);
event WIAOwnershipTransferred(
address indexed previousOwner,
address indexed newOwner,
uint256 timestamp
);
event WIAEmergencyStop(
address indexed triggeredBy,
string reason,
bool paused,
uint256 timestamp
);
event WIAAccessGranted(
address indexed user,
bytes32 indexed role,
address indexed grantedBy,
uint256 timestamp
);
event WIAAccessRevoked(
address indexed user,
bytes32 indexed role,
address indexed revokedBy,
uint256 timestamp
);
// Contract-specific events follow naming convention
event WIATokenTransfer(
address indexed from,
address indexed to,
uint256 value,
bytes data,
uint256 timestamp
);
event WIATokenApproval(
address indexed owner,
address indexed spender,
uint256 value,
uint256 timestamp
);
event WIATokenMint(
address indexed to,
uint256 amount,
address indexed minter,
uint256 timestamp
);
event WIATokenBurn(
address indexed from,
uint256 amount,
uint256 timestamp
);
Error Handling Standards
Custom Errors (Gas Efficient)
// WIA Standard Errors (using custom errors for gas efficiency)
error WIAUnauthorized(address caller, bytes32 requiredRole);
error WIAInsufficientBalance(address account, uint256 requested, uint256 available);
error WIAInvalidAddress(address provided, string reason);
error WIAContractPaused();
error WIAInvalidAmount(uint256 amount, string reason);
error WIATransferFailed(address from, address to, uint256 amount);
error WIAApprovalFailed(address owner, address spender, uint256 amount);
error WIABlacklisted(address account);
error WIAUpgradeFailed(address implementation, string reason);
error WIAInitializationFailed(string reason);
// Usage in contract
contract WIASecureToken {
mapping(address => uint256) private _balances;
mapping(address => bool) private _blacklist;
bool private _paused;
function transfer(address to, uint256 amount) public returns (bool) {
if (_paused) revert WIAContractPaused();
if (to == address(0)) revert WIAInvalidAddress(to, "Zero address");
if (_blacklist[msg.sender]) revert WIABlacklisted(msg.sender);
if (_blacklist[to]) revert WIABlacklisted(to);
uint256 balance = _balances[msg.sender];
if (balance < amount) {
revert WIAInsufficientBalance(msg.sender, amount, balance);
}
_balances[msg.sender] = balance - amount;
_balances[to] += amount;
emit WIATokenTransfer(msg.sender, to, amount, "", block.timestamp);
return true;
}
}
Type Definitions
Standard Data Structures
// WIA Standard Structs
struct WIAContractMetadata {
string name;
string symbol;
uint8 decimals;
string version;
uint256 totalSupply;
bool upgradeable;
bool paused;
}
struct WIADeploymentInfo {
uint256 chainId;
address contractAddress;
address deployer;
uint256 blockNumber;
uint256 timestamp;
bytes32 txHash;
}
struct WIASecurityConfig {
bool reentrancyGuard;
bool pausable;
bool blacklistEnabled;
uint256 maxTransactionAmount;
uint256 dailyLimit;
address[] trustedOracles;
}
struct WIAUpgradeProposal {
address newImplementation;
uint256 proposedAt;
uint256 executeAfter;
address proposer;
string reason;
bool executed;
bool cancelled;
}
struct WIAUserData {
uint256 balance;
uint256 lockedBalance;
uint256 lastTransactionTime;
bool isBlacklisted;
bytes32[] activeRoles;
}
NatSpec Documentation Standard
Complete documentation using NatSpec format:
/// @title WIA Secure Token
/// @author Your Organization
/// @notice A secure ERC-20 token with advanced features
/// @dev Implements WIA-FIN-007 Phase 1 data standards
/// @custom:security-contact security@example.com
contract WIASecureToken is ERC20, Ownable2Step, ReentrancyGuard {
/// @notice Transfers tokens to a recipient
/// @dev Implements checks-effects-interactions pattern
/// @param to The address to receive tokens
/// @param amount The amount of tokens to transfer
/// @return success True if the transfer succeeded
/// @custom:emits WIATokenTransfer
/// @custom:requires Contract must not be paused
/// @custom:requires Recipient must not be blacklisted
/// @custom:requires Sender must have sufficient balance
function transfer(address to, uint256 amount)
public
override
whenNotPaused
nonReentrant
returns (bool success)
{
// Implementation
}
/// @inheritdoc IERC20
/// @custom:gas-estimate 46000
function approve(address spender, uint256 amount)
public
override
returns (bool)
{
// Implementation
}
}
Validation and Testing
WIA-FIN-007 Phase 1 compliance requires passing automated validation:
// Example validation script
import { WIAValidator } from '@wia/validator';
const validator = new WIAValidator();
// Validate metadata
const metadataValid = await validator.validateMetadata('./metadata.json');
console.log('Metadata valid:', metadataValid);
// Validate ABI
const abiValid = await validator.validateABI('./abi.json');
console.log('ABI valid:', abiValid);
// Validate bytecode
const bytecodeValid = await validator.validateBytecode('./bytecode.bin');
console.log('Bytecode valid:', bytecodeValid);
// Validate storage layout
const storageValid = await validator.validateStorageLayout('./storage.json');
console.log('Storage layout valid:', storageValid);
// Generate compliance report
const report = await validator.generateReport({
metadata: './metadata.json',
abi: './abi.json',
bytecode: './bytecode.bin',
storageLayout: './storage.json'
});
console.log('WIA-FIN-007 Phase 1 Compliance:', report.compliant);
console.log('Score:', report.score, '/100');
console.log('Issues:', report.issues);
Key Takeaways
- Comprehensive metadata enables better tooling and security analysis
- Extended ABI format provides validation and documentation
- Optimized storage layouts save significant gas costs
- Standardized events and errors improve debugging and monitoring
- Proper documentation using NatSpec is mandatory
- Automated validation ensures compliance
Phase 1 establishes the foundation for WIA-FIN-007 compliance. Next, we'll explore Phase 2 API interfaces that build upon these data standards.