Skip to main content

Security Considerations

Security architecture and best practices for Lunarys Protocol.

Overview

Lunarys Protocol combines traditional smart contract security with FHE-specific considerations. This document outlines the security model and known considerations.

Smart Contract Security

Access Control

The protocol uses OpenZeppelin's Ownable for administrative functions:

FunctionAccess
bootstrapOwner only
setPositionNFTOwner only
setProtocolFeeOwner only
configureHooksOwner only
claimProtocolFeesOwner only
swapExactAForBPublic
contributeLiquidityPublic
removeLiquidityPosition owner
claimFeesPosition owner

Reentrancy Protection

All state-changing functions use OpenZeppelin's ReentrancyGuard:

function swapExactAForB(
InEuint64 memory amountInEnc,
address recipient,
bytes calldata hookContext
) external ensureInitialized nonReentrant

Integer Safety

  • Solidity 0.8.25 with built-in overflow protection
  • FHE operations maintain encrypted precision
  • Explicit type conversions between encrypted types

FHE Security Model

Encryption Guarantees

PropertyGuarantee
Balance PrivacyOnly owner can decrypt their balance
Swap Amount PrivacyAmounts are encrypted end-to-end
Reserve PrivacyPool reserves are never publicly revealed
Position PrivacyLP amounts are encrypted

Permission System

FHE values require explicit permissions:

// Grant permission to contract
FHE.allowThis(reserveA);

// Grant permission to user
FHE.allow(balance, user);

Permissions are managed by:

  • Contract: allowThis for internal operations
  • Users: allow for value owners
  • Transfers: Recipients get automatic permissions

Trust Assumptions

  1. Fhenix CoFHE Network: Decryption requires network participation
  2. Key Management: User keys are managed client-side
  3. Smart Contract: Contract logic is transparent and auditable

Known Considerations

Information Leakage

While values are encrypted, some information is observable:

ObservableNot Observable
Transaction senderSwap amounts
Token addressesPool reserves
Swap directionUser balances
Gas usageLP position sizes
Transaction timingFee amounts

MEV Considerations

  • Front-running: Reduced but not eliminated
  • Sandwich attacks: Mitigated by hidden amounts
  • Transaction ordering: Still visible to block producers

Economic Attacks

  • Price manipulation: Possible if pool is thinly traded
  • Flash loan attacks: Encrypted reserves complicate but don't prevent
  • Griefing: Gas costs limit spam attacks

Security Measures

Input Validation

// Validate recipient
if (recipient == address(0)) revert InvalidRecipient();

// Validate fee parameters
require(bps <= MAX_PROTOCOL_FEE_BPS, "PrivacyPool: exceeds-max-protocol-fee");

// Validate pool state
require(reservesInitialized, "PrivacyPool: reserves-not-initialized");

Position Verification

// Verify ownership
if (owner != msg.sender) revert NotPositionOwner(tokenId, msg.sender);

// Verify token match
if (position.token0 != address(assetA) || position.token1 != address(assetB)) {
revert PositionTokenMismatch(tokenId);
}

Fee Bounds

uint32 public constant MAX_PROTOCOL_FEE_BPS = 10_000; // 1% maximum

require(bps <= MAX_PROTOCOL_FEE_BPS, "PrivacyPool: exceeds-max-protocol-fee");

Audit Status

Current audit status:

ComponentStatus
PrivacyPoolPending
PoolFactoryPending
PositionNFTPending
TestFHERC20Test only

Planned audits:

  • Smart contract logic review
  • FHE integration review
  • Economic security analysis

Bug Bounty

A bug bounty program will be announced before mainnet launch. Categories include:

  • Critical: Fund loss vulnerabilities
  • High: Privacy leakage
  • Medium: Incorrect calculations
  • Low: Gas optimizations, edge cases

Responsible Disclosure

To report security issues:

  1. Do not disclose publicly
  2. Provide detailed reproduction steps
  3. Allow time for patching
  4. Coordinate disclosure timing

Best Practices for Users

Wallet Security

  • Use hardware wallets for significant funds
  • Verify contract addresses before transactions
  • Review transaction details before signing

Transaction Security

  • Set appropriate gas limits (FHE is expensive)
  • Verify recipient addresses
  • Understand the privacy model

Position Management

  • Keep track of position NFT IDs
  • Claim fees regularly
  • Monitor pool health indicators

Best Practices for Integrators

Contract Interaction

// Verify contract addresses
const KNOWN_POOLS = new Set(['0x...', '0x...'])
if (!KNOWN_POOLS.has(poolAddress)) {
throw new Error('Unknown pool address')
}

// Set explicit gas limits
const tx = await pool.swapExactAForB(
encryptedAmount,
recipient,
'0x',
{ gasLimit: 1_000_000n }
)

Error Handling

try {
await pool.swapExactAForB(...)
} catch (error) {
if (error.message.includes('reserves-not-initialized')) {
// Pool not bootstrapped
} else if (error.message.includes('InvalidRecipient')) {
// Bad recipient address
}
// Handle other cases
}

Event Monitoring

pool.on('SwapExecuted', (sender, recipient, aForB, amountInHandle, amountOutHandle) => {
// Log swap (handles only, values encrypted)
console.log(`Swap by ${sender}: direction=${aForB}`)
})

Upgrades and Migrations

Current Model

Contracts are currently non-upgradeable. This provides:

  • Immutable logic guarantees
  • No admin key risks
  • Simplified security model

Future Considerations

Upgradeability may be added for:

  • Bug fixes
  • Feature additions
  • Gas optimizations

Any upgrade mechanism will include:

  • Timelocks
  • Multi-sig requirements
  • Community governance