OMEGA Best Practices

Guidelines for writing secure, efficient, and maintainable OMEGA smart contracts

Security Best Practices

Input Validation

Always validate inputs to prevent unexpected behavior:

function transfer(address to, uint256 amount) public returns (bool) {
    require(to != address(0), "Invalid recipient address");
    require(amount > 0, "Amount must be positive");
    require(balances[msg.sender] >= amount, "Insufficient balance");
    
    // Function logic here
}

Reentrancy Protection

Use the checks-effects-interactions pattern:

function withdraw(uint256 amount) public {
    // Checks
    require(balances[msg.sender] >= amount, "Insufficient balance");
    
    // Effects
    balances[msg.sender] -= amount;
    
    // Interactions
    payable(msg.sender).transfer(amount);
}

Access Control

blockchain SecureContract {
    state {
        address owner;
        mapping(address => bool) admins;
    }
    
    modifier only_owner() {
        require(msg.sender == owner, "Only owner can call this");
        _;
    }
    
    modifier only_admin() {
        require(admins[msg.sender], "Only admin can call this");
        _;
    }
    
    function set_admin(address admin, bool status) public only_owner {
        admins[admin] = status;
    }
}

Gas Optimization

Use Appropriate Data Types

// Good: Use smaller types when possible
uint8 small_number;
uint32 medium_number;

// Avoid: Using uint256 for small values unnecessarily
uint256 tiny_flag; // Wasteful for boolean-like values

Pack Struct Variables

// Good: Packed struct (saves gas)
struct User {
    uint128 balance;    // 16 bytes
    uint64 timestamp;   // 8 bytes
    uint32 id;          // 4 bytes
    uint32 status;      // 4 bytes
    // Total: 32 bytes (1 storage slot)
}

// Avoid: Unpacked struct
struct BadUser {
    uint256 balance;    // 32 bytes
    uint256 timestamp;  // 32 bytes
    uint256 id;         // 32 bytes
    // Total: 96 bytes (3 storage slots)
}

Batch Operations

function batch_transfer(address[] recipients, uint256[] amounts) public {
    require(recipients.length == amounts.length, "Array length mismatch");
    
    for (uint256 i = 0; i < recipients.length; i++) {
        transfer(recipients[i], amounts[i]);
    }
}

Code Organization

Use Meaningful Names

// Good
function calculate_compound_interest(uint256 principal, uint256 rate, uint256 time) 
    public pure returns (uint256) {
    // Implementation
}

// Avoid
function calc(uint256 p, uint256 r, uint256 t) public pure returns (uint256) {
    // Implementation
}

Modular Design

// Separate concerns into different contracts
blockchain TokenLogic {
    // Core token functionality
}

blockchain TokenGovernance {
    // Governance-related functions
}

blockchain TokenVesting {
    // Vesting and time-locked functions
}

Documentation

/// @title ERC20 Token Implementation
/// @author Your Name
/// @notice This contract implements a basic ERC20 token
/// @dev All function calls are currently implemented without side effects
blockchain MyToken {
    /// @notice Transfer tokens to a specified address
    /// @param to The address to transfer to
    /// @param amount The amount to be transferred
    /// @return success True if the transfer was successful
    function transfer(address to, uint256 amount) public returns (bool success) {
        // Implementation
    }
}

Cross-Chain Best Practices

Handle Network Differences

function get_network_specific_data() public view returns (uint256) {
    #[target(evm)]
    return block.number;
    
    #[target(solana)]
    return Clock::get().slot;
    
    #[target(cosmos)]
    return env.block.height;
}

Cross-Chain Communication

@cross_chain(target = "solana")
function bridge_tokens(bytes32 solana_recipient, uint256 amount) public {
    require(amount > 0, "Amount must be positive");
    require(balances[msg.sender] >= amount, "Insufficient balance");
    
    // Lock tokens on source chain
    balances[msg.sender] -= amount;
    locked_balances += amount;
    
    // Emit cross-chain event
    emit CrossChainTransfer(msg.sender, solana_recipient, amount, "solana");
}

Testing Best Practices

Comprehensive Test Coverage

// Test file: tests/token_tests.omega
test "should transfer tokens correctly" {
    let token = deploy_token("Test", "TST", 1000);
    let result = token.transfer(user1, 100);
    
    assert(result == true);
    assert(token.balance_of(user1) == 100);
    assert(token.balance_of(deployer) == 900);
}

test "should fail transfer with insufficient balance" {
    let token = deploy_token("Test", "TST", 100);
    
    expect_revert(
        token.transfer(user1, 200),
        "Insufficient balance"
    );
}

Edge Case Testing

test "should handle zero transfers" {
    let token = deploy_token("Test", "TST", 1000);
    let result = token.transfer(user1, 0);
    
    // Define expected behavior for zero transfers
    assert(result == false); // or true, depending on design
}

test "should handle maximum values" {
    let token = deploy_token("Test", "TST", type(uint256).max);
    // Test behavior with maximum possible values
}

Performance Optimization

Minimize Storage Operations

// Good: Single storage write
function update_user_data(uint256 new_balance, uint256 new_timestamp) public {
    UserData storage user = users[msg.sender];
    user.balance = new_balance;
    user.last_update = new_timestamp;
}

// Avoid: Multiple storage operations
function bad_update_user_data(uint256 new_balance, uint256 new_timestamp) public {
    users[msg.sender].balance = new_balance;      // Storage write 1
    users[msg.sender].last_update = new_timestamp; // Storage write 2
}

Use Events for Data Storage

// Use events for historical data that doesn't need to be queried on-chain
event UserAction(
    address indexed user,
    string action_type,
    uint256 timestamp,
    bytes data
);

function perform_action(string action_type, bytes data) public {
    // Minimal on-chain storage
    user_action_count[msg.sender]++;
    
    // Detailed data in events
    emit UserAction(msg.sender, action_type, block.timestamp, data);
}

Deployment Best Practices

Environment Configuration

# omega.toml
[deployment.testnet]
gas_limit = 8000000
gas_price = "20 gwei"
confirmations = 2

[deployment.mainnet]
gas_limit = 6000000
gas_price = "auto"
confirmations = 5

Gradual Rollout

  1. Deploy to testnet first
  2. Conduct thorough testing
  3. Deploy to mainnet with limited functionality
  4. Gradually enable full features

Common Pitfalls to Avoid

⚠️ Integer Overflow/Underflow

Always use safe math operations or built-in overflow checks.

⚠️ Uninitialized Storage

Initialize all state variables properly in the constructor.

⚠️ Gas Limit Issues

Be aware of gas limits when processing arrays or loops.

⚠️ Front-Running

Consider commit-reveal schemes for sensitive operations.