# Smart Contract Architecture

### Architecture

#### Core Components

**1. Factory Pattern with Diamond Proxies**

The protocol implements the EIP-2535 Diamond Standard (multi-facet proxy pattern) combined with a factory deployment system:

* `RainDeployer`: Factory contract that deploys new prediction market pools
* `RainPoolDiamond`: Diamond proxy instances representing individual prediction markets
* `Facets`: Modular contracts containing specific functionality

**2. RainDeployer (Factory Contract)**

The RainDeployer is an upgradeable factory contract (UUPS pattern) responsible for:

**Key Features:**

* Deploys new RainPoolDiamond instances
* Manages global protocol parameters (fees, addresses, token settings)
* Maintains registry of all deployed pools
* Integrates with oracle factory for dispute resolution

**State Variables:**

```
solidity
- totalPools: Total number of pools created
- userPools: Mapping of user addresses to their created pools
- allPools: Global registry of all pools
- createdPools: Verification mapping for pool authenticity
```

**Fee Structure:**

* Platform Fee (default: 2.5%)
* Liquidity Provider Fee (default: 1.2%)
* Creator Fee (default: 1.2%)
* Result Resolver Fee (default: 0.1%)
* Oracle Fixed Fee (configurable)

**Volume-Based Fee Discounts:**

* Tier 1 (≥500 base tokens): 10% discount
* Tier 2 (≥1,000 base tokens): 25% discount
* Tier 3 (≥1,500 base tokens): 40% discount

**3. RainPoolDiamond**

Each prediction market is deployed as a Diamond proxy with the following characteristics:

**Initialization:**

solidity constructor( IDiamondCut.FacetCut\[] memory \_diamondCut, IRainPool.Params memory params )

**Parameters:**

* `isPublic`: Public (AI-resolved) or private (owner-resolved) pool
* `resolverIsAI`: Whether the pool owner delegates resolution to AI
* `poolOwner`: Creator of the prediction market
* `referrer`: Optional referrer for fee sharing
* `startTime`: When the market opens for trading
* `endTime`: When the market closes
* `numberOfOptions`: Number of outcomes (minimum 2)
* `oracleEndTime`: Deadline for oracle resolution
* `initialLiquidity`: Bootstrap liquidity amount
* `liquidityPercentages`: Distribution across options

**Facet System**

The protocol functionality is divided into specialized facets:

**1. TradingFacet**

Handles all trading operations: Functions: enterOption(uint256 option, uint256 amount): Buy shares in an outcome enterLiquidity(uint256 totalAmount): Provide liquidity across all options placeSellOrder(uint256 option, uint256 price, uint256 votes): Create sell order placeBuyOrder(uint256 option, uint256 price, uint256 amount): Create buy order Trading Mechanics: Automated Market Maker (AMM) with dynamic pricing Order book for limit orders (tick spacing: 0.01 ETH) FIFO order execution Price range: 0.01 to 0.99 ETH per share Key Features: Automatic order matching against order book Price impact calculation Fee deduction on order execution (0.5% + creator fee) Escrow system for pending orders

**2. ResolutionFacet**

Manages pool finalization and outcome determination: Functions: closePool(): Finalizes the market and calculates fee distributions chooseWinner(uint256 option): Resolver selects winning outcome Process: Pool closes after endTime Fees are distributed: Platform share → swapped for RAIN token and burned Creator share → split between creator and referrer (if any) Liquidity share → reserved for LPs Resolver share → paid to resolver Winning share → distributed to winning outcome holders Burn Mechanism: The protocol attempts to swap platform fees for RAIN tokens via Uniswap V3 and burn them. If the swap fails, base tokens are sent to the platform address.

**3. DisputeFacet**

**Implements a two-tier dispute resolution system:**

**Dispute Process:**

**First Dispute:**

* Any participant can open a dispute within the dispute window (1 hour)
* Requires collateral (0.1% of pool funds, max $1,000)
* Dispute resolver AI makes a new decision
* If disputer is correct, collateral is refunded
* If original resolver was correct, collateral goes to original resolver

**Appeal (Second Dispute):**

* If participants still disagree, they can appeal
* Creates an oracle via the oracle factory
* Number of oracles determined by pool size
* Oracle voting determines final outcome
* Appeal collateral same as dispute collateral

**States:**

```
solidity

enum PoolState {
    NotDisputed,
    Disputed,
    Appealed
}
```

**4. ClaimFacet**

Handles reward distribution:

**Function:**

* `claim()`: Users claim their winnings and liquidity rewards

**Claim Logic:**

1. Checks dispute window has elapsed (public pools)
2. Resolves any pending disputes/appeals
3. Distributes dispute collateral
4. Calculates user rewards:
   * Liquidity rewards: Proportional to liquidity provided
   * Winning rewards: Proportional to winning shares held
5. Resets user positions to prevent abuse

**Restrictions:**

* Users cannot claim with active sell orders on winning option
* Users cannot claim with active buy orders on any option
* One claim per user per pool

**5. CancelOrderFacet**

Order management:

**Functions:**

* `cancelSellOrders(uint256[] memory option, uint256[] memory price, uint256[] memory orderID)`
* `cancelBuyOrders(uint256[] memory option, uint256[] memory price, uint256[] memory orderID)`

**Features:**

* Batch order cancellation
* Returns escrowed assets
* Updates order book linked lists
* Validates caller is order creator

**6. InfoFacet**

Read-only informational functions:

**Key Functions:**

* `getDynamicPayout(address user)`: Calculate expected payout for each outcome
* `getEntryShares(uint256 option, uint256 amount)`: Simulate share purchase
* `getCurrentPrice(uint256 option)`: Get current option price
* `getAmountRequired(...)`: Calculate amount needed to reach target price
* `totalOrders()`: Active order count

**7. GetterFacet**

State variable accessors:

Provides read access to all storage variables including:

* Pool parameters
* User positions
* Order book state
* Fee structures
* Constants (TICK\_SPACING, FEE\_MAGNIFICATION, etc.)

**8. DiamondCutFacet**

Diamond upgrade functionality (standard EIP-2535)

**9. DiamondLoupeFacet**

Diamond introspection (standard EIP-2535)

### Key Mechanisms

#### 1. Automated Market Maker (AMM)

**Pricing Formula:**

```
price = (optionFunds * PRICE_MAGNIFICATION) / allFunds
```

Where:

* `PRICE_MAGNIFICATION = 1e18` (for precision)
* `optionFunds`: Total funds in specific option
* `allFunds`: Total funds across all options

**Share Calculation:**

```
shares = (amount * PRICE_MAGNIFICATION) / impactedPrice
```

Where `impactedPrice` accounts for the price after adding the new amount.

#### 2. Order Book System

**Structure:**

* Linked list implementation for each price level
* Separate books for buy and sell orders
* FIFO execution within price level
* Tick spacing: 0.01 ETH (1% increments)

**Execution Priority:**

1. Match against order book first (up to current AMM price for sells)
2. Execute remaining amount through AMM
3. If pool closed and winner not decided, limit to 0.99 ETH

#### 3. Liquidity Provision

**Proportional Distribution:** Liquidity is distributed across all options proportionally to existing funds:

```
amountPerOption[i] = (totalAmount * totalFunds[i]) / allFunds
sharesPerOption[i] = getReturnedShares(i, amountPerOption[i])
```

**Rewards:** Liquidity providers earn:

* Fixed percentage of total pool (liquidityFee)
* Distributed proportionally to liquidity provided
* Paid out after pool resolution

#### 4. Dispute Resolution

**Timeline:**

```
Pool End → Winner Selected → Dispute Window (1 hour) → Claims Open
                ↓
            Dispute Opened → AI Resolution → Dispute Window → Claims Open
                ↓
            Appeal Opened → Oracle Creation → Oracle Voting → Claims Open
```

**Oracle Creation:**

Number of oracles based on pool size: baseOracles + (resolverShare / 10) Minimum: numberOfOptions + 1 Maximum: 100 oracles Oracle voting period: configurable via oracleEndTime

**5. Fee Distribution**

**On Trade Entry:**

Immediate platform fee deduction (with volume discounts) Fees accumulate in contract

**On Pool Close:**

* Platform fee: Swapped to RAIN and burned
* Creator fee: Split between creator and referrer
* Liquidity fee: Reserved for LP claims
* Resolver fee: Paid on first claim

**On Order Execution:**

* 0.5% execution fee to platform
* Creator fee to pool creator/referrer
* Storage Architecture

**Diamond Storage Pattern**

Uses the diamond storage pattern with a single struct at a deterministic slot:

```
solidity
bytes32 constant DIAMOND_STORAGE_POSITION = 
    keccak256("diamond.standard.diamond.storage");
```

**Key Storage Variables:**

* Price and vote tracking per option
* User positions (votes, liquidity, escrow)
* Order books (linked lists)
* Fee accumulations
* Dispute/appeal state
* Pool metadata

#### Linked List Implementation

Order books use a linked list structure for efficient FIFO execution:

```
solidity
struct LinkedList {
    mapping(int256 => Node) nodes;
    int256 headIndex;
    int256 tailIndex;
    int256 count;
    bool isInitialized;
}
```

#### Security Features

**1. Access Control**

* Only resolver can select winner
* Only pool owner/resolver can close pool early
* Only order creators can cancel orders
* Only factory can create oracles

**2. Validation**

* Option bounds checking
* Price tick validation (must be multiple of TICK\_SPACING)
* Amount validation (prevents dust)
* Winner bounds checking
* Array length matching for batch operations

**3. Reentrancy Protection**

* Uses OpenZeppelin's SafeERC20
* State updates before external calls Try-catch for external integrations

**4. Economic Security**

* Dispute collateral requirements
* Order escrow system
* Fee on early order cancellation
* Volume-based fee incentives

#### Integration Points

**1. Oracle Factory**

* Creates external oracle contracts for appeals
* Manages oracle reward distribution
* Validates oracle outcomes

**2. Uniswap V3**

* Swaps platform fees for RAIN token
* Multi-hop routing: baseToken → WETH → RAIN
* Slippage protection (3%)
* Fallback to direct transfer on failure

**3. RAIN Token**

* Burn mechanism for deflation
* Reward distribution
* Governance (implied)

#### Upgradeability

**RainDeployer**

* UUPS upgradeable pattern
* Owner-only upgrade authorization
* Preserves storage layout
* Can update facet addresses for new pools

**RainPoolDiamond**

* Diamond standard upgradeability
* Can add/replace/remove functions
* Immutable once deployed (no upgrade mechanism in pool itself)
* Factory controls facets for new deployments

#### Events

All major operations emit events for off-chain indexing:

**Trading:**

* `EnterOption`, `EnterLiquidity`
* `PlaceSellOrder`, `PlaceBuyOrder`
* `ExecuteSellOrder`, `ExecuteBuyOrder`
* `CancelSellOrder`, `CancelBuyOrder`
* `Sync` (price updates)

**Resolution:**

* `ClosePool`
* `ChooseWinner`, `ChooseWinnerDispute`, `ChooseWinnerAppeal`
* `CreateOracle`
* `OpenDispute`, `OpenAppeal`

**Claims:**

* `Claim`
* `PlatformClaim`, `CreatorClaim`, `ReferrerClaim`, `ResolverClaim`
* `RainTokenBurned`

**Gas Optimization**

1. Linked Lists: O(1) insertions and deletions
2. Packed Storage: Efficient storage layout
3. Batch Operations: Cancel multiple orders in one transaction

**Limitations**

1. Order Book Depth: Gas costs increase with order book depth
2. Option Limit: Maximum number of options (though not explicitly limited, gas costs grow linearly)
3. Oracle Dependency: Appeals rely on external oracle system
4. Price Precision: Limited by TICK\_SPACING (0.01 ETH increments)
5. Burn Mechanism: Depends on RAIN token liquidity on Uniswap

#### Best Practices for Integration

**Creating a Pool**

1. Approve baseToken for initialLiquidity + oracleFixedFee
2. Call createPool with properly formatted parameters
3. Verify pool creation via createdPools mapping

**Trading**

1. Check pool is live: block.timestamp >= startTime && block.timestamp < endTime
2. Get expected shares: getEntryShares(option, amount)
3. Approve baseToken
4. Call `enterOption` or place orders

**Providing Liquidity**

1. Calculate expected distribution: getReturnedLiquidity(amount)
2. Approve baseToken
3. Call enterLiquidity

**Resolution**

1. Wait for endTime
2. Call closePool (owner/resolver can call early)
3. Resolver calls chooseWinner
4. Wait for dispute window (public pools)
5. Users call claim

**Version:**

Based on Solidity 0.8.26 License: MIT Diamond Standard: EIP-2535 Network: Arbitrum

**------------------------------------------------------------------------------------------------------------------**

Tokens to use as currency (USDT)

DEV: &#x20;

```properties
0xAa359e618220c247dce867164305f2eb737C646D
```

STAGE:

```properties
0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9
```

PRODUCTION:&#x20;

```properties
0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9
```

ALL DEPLOYED FACTORIES

#### ARBITRUM ETH DEV:

**<https://arbiscan.io/address/0x148DA7F2039B2B00633AC2ab566f59C8a4C86313>**

#### ARBITRUM ETH STAGE:

**<https://arbiscan.io/address/0x6109c9f28FE3Ad84c51368f7Ef2d487ca020c561>**

#### ARBITRUM ETH PRODUCTION:

**<https://arbiscan.io/address/0xccCB3C03D9355B01883779EF15C1Be09cf3623F1>**


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://rain-4.gitbook.io/rain-docs/smart-contract-architecture.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
