Security

Security is paramount in DeFi protocols. RealSafe has been designed with multiple layers of security to protect user funds and ensure trustless operations.

Security Features

1. Battle-Tested Patterns

RealSafe is based on the UNCX locker architecture, which has secured millions of dollars in liquidity across thousands of projects. We've adapted and enhanced these proven patterns for modern DEX protocols.

// UNCX-inspired lock structure
struct Lock {
    uint256 lockId;         // Unique identifier
    uint256 nftId;          // NFT token ID
    address owner;          // Current owner
    address pendingOwner;   // 2-step transfer
    address pool;           // Pool address (cached)
    address token0;         // Token0 (cached)
    address token1;         // Token1 (cached)
    uint128 liquidity;      // Liquidity amount
    uint256 unlockDate;     // Unlock timestamp
    address collectAddress; // Fee recipient
    bool isActive;          // Status flag
    address condition;      // Optional condition
}

2. OpenZeppelin Security Primitives

All contracts inherit from OpenZeppelin's audited libraries (v5.4.0):

import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import {Pausable} from "@openzeppelin/contracts/utils/Pausable.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

Benefits:

  • ReentrancyGuard: Prevents reentrancy attacks

  • Pausable: Emergency pause capability

  • Ownable: Secure ownership management

  • SafeERC20: Safe token transfers

3. Reentrancy Protection

All state-changing functions use the nonReentrant modifier:

function lockPosition(
    uint256 nftId,
    uint256 unlockDate,
    address collectAddress,
    address condition
) external payable nonReentrant whenNotPaused returns (uint256) {
    // Function logic
}

Protected Functions:

  • lockPosition() / lockLP()

  • claimFees()

  • withdraw() / unlock()

  • addToLock()

4. Pausable Contract

Owner can pause all operations in case of emergency:

function emergencyPause() external onlyOwner {
    _pause();
    emit EmergencyPaused(msg.sender);
}

function emergencyUnpause() external onlyOwner {
    _unpause();
    emit EmergencyUnpaused(msg.sender);
}

When Paused:

  • Cannot create new locks

  • Cannot claim fees

  • Cannot unlock positions

  • Emergency withdrawals still work (owner only)

5. Emergency Withdrawals

Owner can rescue stuck tokens/NFTs in emergencies:

function emergencyWithdraw(
    address token,
    uint256 amount,
    address to
) external onlyOwner {
    // Withdraw ERC20 or native tokens
}

function emergencyWithdrawNFT(
    address nftContract,
    uint256 tokenId,
    address to
) external onlyOwner {
    // Withdraw stuck NFTs
}

Important: Emergency withdrawals should only be used for:

  • Rescuing tokens sent by mistake

  • Recovering from contract bugs

  • Never to steal user funds (would break trust)

6. Two-Step Ownership Transfer

Lock ownership uses a two-step transfer pattern to prevent accidental transfers:

// Step 1: Current owner initiates transfer
function transferLockOwnership(uint256 lockId, address newOwner) external {
    // Sets pendingOwner
}

// Step 2: New owner accepts transfer
function acceptLockOwnership(uint256 lockId) external {
    // Transfers ownership
}

7. Input Validation

All inputs are validated to prevent common vulnerabilities:

// Example validations
if (msg.value < creationFee) revert InsufficientCreationFee();
if (unlockDate <= block.timestamp) revert InvalidUnlockTime();
if (unlockDate > block.timestamp + 365 days * 10) revert InvalidUnlockTime();
if (condition != address(0) && !_isContract(condition)) revert InvalidCondition();
if (amount == 0) revert ZeroAmount();

Validated Parameters:

  • Non-zero amounts

  • Valid addresses

  • Reasonable unlock times (max 10 years)

  • Valid contract addresses for conditions

8. Access Control

Functions are restricted based on role:

Function
Access
Check

lockPosition()

Anyone

Must pay creation fee

claimFees()

Lock owner

msg.sender == lock.owner

unlock()

Lock owner

msg.sender == lock.owner

extendLock()

Lock owner

msg.sender == lock.owner

transferLockOwnership()

Lock owner

msg.sender == lock.owner

setCollectAddress()

Lock owner

msg.sender == lock.owner


Known Risks & Mitigations

Risk 1: Contract Administration

Risk: Contract owner has certain administrative privileges for maintenance and emergency situations.

Mitigation:

  • Owner cannot access user funds

  • Owner cannot prevent unlocking

  • Emergency pause is for security only

  • All admin actions are transparent on-chain

Risk 2: Smart Contract Bugs

Risk: Undiscovered bugs could lock user funds permanently.

Mitigation:

  • Based on proven UNCX architecture

  • Comprehensive test suite (95%+ coverage)

  • Emergency withdrawal mechanisms

  • External security audit (planned)

Risk 3: Price Oracle Manipulation

Risk: Lock fees based on position value could be manipulated.

Current Status: Lock fees are currently a flat percentage and not dependent on external oracles.

Future Mitigation (if oracles added):

  • Use TWAP (Time-Weighted Average Price)

  • Multiple oracle sources

  • Sanity checks on price data

Risk 4: Flash Loan Attacks

Risk: Attacker uses flash loan to manipulate state.

Mitigation:

  • ReentrancyGuard on all critical functions

  • Checks-Effects-Interactions pattern

  • No reliance on msg.sender balance

  • No external oracle calls in critical paths

Risk 5: Front-Running

Risk: Users could be front-run when locking/unlocking.

Mitigation:

  • Minimal: Lock parameters are time-based, not price-based

  • Users can set slippage tolerance

  • Use private RPCs or MEV-protected RPCs

Risk 6: Condition Contract Exploits

Risk: Malicious condition contracts could prevent unlocking.

Mitigation:

  • Condition calls wrapped in try/catch

  • Falls back to time-based unlock if condition fails

  • Users should only use verified condition contracts

  • Whitelist of approved condition contracts (planned)

// Safe condition check with fallback
if (lock.condition != address(0)) {
    try ILockCondition(lock.condition).isUnlocked(address(this), lockId) 
        returns (bool unlocked) {
        return unlocked;
    } catch {
        // Fall back to time-based unlock
        return false;
    }
}

Best Practices for Users

For Lock Creators

1. Verify Addresses

  • Double-check all addresses before locking

  • Ensure you're on the correct network

  • Verify contract addresses on block explorer

2. Start Small

  • Test with small amounts first

  • Verify you can claim fees

  • Ensure unlock works as expected

3. Secure Your Keys

  • Use hardware wallet for valuable locks

  • Never share private keys

  • Enable 2FA on exchanges/wallets

4. Understand Lock Terms

  • Know your unlock date

  • Understand fee structure

  • Test claiming fees before relying on it

5. Backup Important Data

  • Save lock IDs

  • Screenshot transaction hashes

  • Document unlock dates

For Developers

1. Test Thoroughly

  • Run full test suite before deploying

  • Test on testnet first

  • Verify all contracts

2. Monitor Events

  • Set up event monitoring

  • Track unusual activity

  • Alert on suspicious patterns

3. Gradual Rollout

  • Start on testnet

  • Limited beta on mainnet

  • Full launch after battle testing

4. Documentation

  • Clear user guides

  • Transaction simulation

  • Error message explanations


Security Checklist

Before Locking

After Locking

Before Unlocking


Emergency Procedures

If You Suspect a Bug

  1. Do NOT interact with the contract

  2. Contact the team immediately:

  3. Provide Details:

    • Transaction hash

    • Contract address

    • Steps to reproduce

    • Impact assessment

If Contract is Paused

  1. Check Announcements:

  2. Wait for Resolution:

    • Team will investigate

    • Issue will be communicated

    • Timeline for fix will be announced

  3. Emergency Unlock (if necessary):

    • Owner can enable emergency unlocks

    • Users can withdraw regardless of time

    • Fees may be waived


Security Resources

Official Documentation

Tools Used

  • Slither: Static analysis

  • Foundry: Testing framework

  • MythX: Automated security analysis

  • Echidna: Property-based fuzzing

Continuous Monitoring

  • Event monitoring via The Graph

  • Treasury balance tracking

  • Gas usage optimization

  • Failed transaction analysis


Contact Security Team


Last Updated: October 2025 Version: 1.0.0

Last updated