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:
| Function | Access |
|---|---|
| bootstrap | Owner only |
| setPositionNFT | Owner only |
| setProtocolFee | Owner only |
| configureHooks | Owner only |
| claimProtocolFees | Owner only |
| swapExactAForB | Public |
| contributeLiquidity | Public |
| removeLiquidity | Position owner |
| claimFees | Position 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
| Property | Guarantee |
|---|---|
| Balance Privacy | Only owner can decrypt their balance |
| Swap Amount Privacy | Amounts are encrypted end-to-end |
| Reserve Privacy | Pool reserves are never publicly revealed |
| Position Privacy | LP 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:
allowThisfor internal operations - Users:
allowfor value owners - Transfers: Recipients get automatic permissions
Trust Assumptions
- Fhenix CoFHE Network: Decryption requires network participation
- Key Management: User keys are managed client-side
- Smart Contract: Contract logic is transparent and auditable
Known Considerations
Information Leakage
While values are encrypted, some information is observable:
| Observable | Not Observable |
|---|---|
| Transaction sender | Swap amounts |
| Token addresses | Pool reserves |
| Swap direction | User balances |
| Gas usage | LP position sizes |
| Transaction timing | Fee 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:
| Component | Status |
|---|---|
| PrivacyPool | Pending |
| PoolFactory | Pending |
| PositionNFT | Pending |
| TestFHERC20 | Test 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:
- Do not disclose publicly
- Provide detailed reproduction steps
- Allow time for patching
- 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