WIA-FIN-007 ๐Ÿ“œ Chapter 4

Phase 1: Data Format

Contract metadata, ABI standardization, bytecode formats, and storage optimization

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.