> ## Documentation Index
> Fetch the complete documentation index at: https://village-docs.villagelabs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Step 3: Allocate Shares

> Distribute shares to eligible participants pro-rata by compensation

## Overview

Step 3 allocates shares from the pool (determined in Step 2) to eligible participants, applying eligibility rules and ERISA caps.

<Info>
  This is where participants actually receive their **annual allocation** of ESOP shares based on their compensation.
</Info>

## Core Responsibilities

<CardGroup cols={2}>
  <Card title="Eligibility Determination" icon="user-check">
    Identify which employees qualify for allocation
  </Card>

  <Card title="Pro-Rata Allocation" icon="percent">
    Distribute shares proportional to eligible compensation
  </Card>

  <Card title="ERISA Compliance" icon="gavel">
    Apply compensation and annual addition caps
  </Card>

  <Card title="Multi-Class Distribution" icon="shapes">
    Allocate across multiple securities in proper proportions
  </Card>
</CardGroup>

***

## Processing Phases

### Phase 1: Determine Eligibility

Employees must meet **all three criteria** to receive allocations:

```python theme={null}
is_eligible = (
    employee.age >= eligibility_age              # e.g., 21
    AND employee.service_years >= eligibility_service_years  # e.g., 1.0
    AND employee.hours_worked >= eligibility_min_hours       # e.g., 1000
)
```

**Example:**

* Eligibility Age: 21
* Eligibility Service: 1 year
* Eligibility Hours: 1,000 hours/year

**Employee A:** Age 35, 5 years service, 2,080 hours → ✅ **Eligible**\
**Employee B:** Age 22, 0.5 years service, 2,080 hours → ❌ **Not eligible** (service)\
**Employee C:** Age 24, 2 years service, 800 hours → ❌ **Not eligible** (hours)

<Note>
  Every employee gets an eligibility evaluation event in the compliance log, regardless of outcome.
</Note>

***

### Phase 2: Calculate Eligible Compensation

Apply the **ERISA Compensation Cap** (IRC §401(a)(17)):

<Tabs>
  <Tab title="Compensation Capping">
    ```python theme={null}
    max_compensation = 345_000  # 2025 ERISA limit (adjusts annually)

    for employee in eligible_employees:
        if employee.compensation > max_compensation:
            capped_compensation = max_compensation
            # Log compensation cap event
        else:
            capped_compensation = employee.compensation
        
        total_eligible_compensation += capped_compensation
    ```

    **Example:**

    * Employee A: $80,000 comp → capped at $80,000 (under limit)
    * Employee B: $250,000 comp → capped at $250,000 (under limit)
    * Employee C: $400,000 comp → capped at $345,000 (over limit) ⚠️

    Total eligible comp = $80K + $250K + $345K = $675,000
  </Tab>

  <Tab title="Why Cap Compensation?">
    **IRS Regulation:** IRC §401(a)(17) limits compensation that can be considered for qualified plan contributions.

    **Purpose:** Prevents disproportionate benefits for highly compensated employees.

    **2025 Limit:** \$345,000 (indexed annually for inflation)

    **Impact:** High earners get allocations based on capped amount, not actual pay.
  </Tab>
</Tabs>

***

### Phase 3: Allocate Shares

Shares are distributed **pro-rata by eligible compensation**:

```python theme={null}
for employee in eligible_employees:
    allocation_ratio = employee.capped_compensation / total_eligible_compensation
    shares_to_allocate = total_share_pool * allocation_ratio
```

**Example Allocation:**

| Employee  | Compensation  | Capped Comp   | Ratio    | Share Pool | Allocation       |
| --------- | ------------- | ------------- | -------- | ---------- | ---------------- |
| A         | \$80,000      | \$80,000      | 11.85%   | 5,000      | 593 shares       |
| B         | \$250,000     | \$250,000     | 37.04%   | 5,000      | 1,852 shares     |
| C         | \$400,000     | \$345,000     | 51.11%   | 5,000      | 2,555 shares     |
| **Total** | **\$730,000** | **\$675,000** | **100%** | **5,000**  | **5,000 shares** |

<Note>
  Notice Employee C's allocation is based on $345K, not their actual $400K compensation.
</Note>

***

### Phase 4: Apply Annual Addition Cap

**ERISA Annual Addition Limit** (IRC §415):

<Warning>
  Maximum value that can be added to an employee's account in a year: **\$69,000** (2025 limit).

  This includes employer contributions, forfeitures allocated, and certain other additions.
</Warning>

<Tabs>
  <Tab title="Cap Enforcement">
    ```python theme={null}
    max_annual_addition = 69_000  # 2025 ERISA limit

    for employee in eligible_employees:
        allocation_value = shares_to_allocate * share_price
        
        if allocation_value > max_annual_addition:
            # Scale down allocation to cap
            shares_to_allocate = max_annual_addition / share_price
            
            # Log annual addition cap event
    ```

    **Example:**

    * Share Price: \$500
    * Employee C allocated: 2,555 shares
    * Value: 2,555 \* $500 = $1,277,500 ⚠️ **WAY OVER**

    **Capped Allocation:**

    * Max value: \$69,000
    * Capped shares: $69,000 / $500 = **138 shares**
    * Employee C receives: 138 shares (not 2,555)
  </Tab>

  <Tab title="High Share Price Impact">
    When share price is high, annual addition cap severely limits allocations:

    **Low Share Price (\$50):**

    * Cap: \$69,000
    * Max shares: $69,000 / $50 = **1,380 shares**

    **Medium Share Price (\$500):**

    * Cap: \$69,000
    * Max shares: $69,000 / $500 = **138 shares**

    **High Share Price (\$5,000):**

    * Cap: \$69,000
    * Max shares: $69,000 / $5,000 = **13.8 shares**

    <Note>
      As companies mature and share price increases, **fewer shares** can be allocated per participant due to this cap.
    </Note>
  </Tab>

  <Tab title="Multi-Class Capping">
    In multi-class mode, cap is applied to the **combined value** across all securities:

    ```python theme={null}
    # Calculate total value across all securities
    total_value = 0
    for security_id, quantity in allocations_by_security.items():
        security_price = securities[security_id].current_share_price
        total_value += quantity * security_price

    # If over cap, scale down ALL securities proportionally
    if total_value > max_annual_addition:
        scale_factor = max_annual_addition / total_value
        for security_id in allocations_by_security.keys():
            allocations_by_security[security_id] *= scale_factor
    ```

    **Example:**

    * Class A allocation: 50 shares @ $600 = $30,000
    * Class B allocation: 100 shares @ $400 = $40,000
    * Total value: $70,000 (over $69K cap)
    * Scale factor: $69,000 / $70,000 = 0.9857

    **Scaled Allocations:**

    * Class A: 50 \* 0.9857 = 49.29 shares
    * Class B: 100 \* 0.9857 = 98.57 shares
    * New total: \$68,996 ✅
  </Tab>
</Tabs>

***

## Multi-Class Allocation

When `multi_class_mode=True`, allocations are distributed **per security**:

<Steps>
  <Step title="Determine Per-Security Pools">
    From Step 2, each security has its own share pool:

    ```python theme={null}
    share_pool_by_security = {
        "CLASS_A": 3_000.0,  # shares available
        "CLASS_B": 2_000.0   # shares available
    }
    ```
  </Step>

  <Step title="Allocate Each Security Pro-Rata">
    ```python theme={null}
    for employee in eligible_employees:
        allocation_ratio = employee.capped_comp / total_eligible_comp
        
        for security_id, pool_quantity in share_pool_by_security.items():
            employee_allocation[security_id] = pool_quantity * allocation_ratio
    ```
  </Step>

  <Step title="Apply Annual Addition Cap">
    Calculate **combined value** and scale if necessary
  </Step>

  <Step title="Update Employee Holdings">
    ```python theme={null}
    for security_id, quantity in employee_allocation.items():
        if not employee.holdings.get(security_id):
            employee.holdings[security_id] = Holding()
        employee.holdings[security_id].shares += quantity
    ```
  </Step>
</Steps>

**Example Multi-Class Allocation:**

| Employee | Comp Ratio | Class A Pool | Class A Alloc | Class B Pool | Class B Alloc |
| -------- | ---------- | ------------ | ------------- | ------------ | ------------- |
| A        | 20%        | 3,000        | 600           | 2,000        | 400           |
| B        | 35%        | 3,000        | 1,050         | 2,000        | 700           |
| C        | 45%        | 3,000        | 1,350         | 2,000        | 900           |

***

## Data Flow

### Inputs

<Tabs>
  <Tab title="From Step 2">
    ```python theme={null}
    {
      "total_shares_for_pool": 5000.0,           # Single-class mode
      "share_pool_by_security": {                # Multi-class mode
        "CLASS_A": 3000.0,
        "CLASS_B": 2000.0
      }
    }
    ```
  </Tab>

  <Tab title="Plan Rules">
    ```python theme={null}
    {
      "eligibility_age": 21,
      "eligibility_service_years": 1.0,
      "eligibility_min_hours": 1000
    }
    ```
  </Tab>

  <Tab title="ERISA Limits">
    ```python theme={null}
    {
      "max_compensation": 345_000,      # §401(a)(17)
      "max_annual_addition": 69_000    # §415
    }
    ```
  </Tab>

  <Tab title="Employee Data">
    ```python theme={null}
    {
      "employee_id": "EMP001",
      "age": 35,
      "service_years": 5.0,
      "hours_worked": 2080,
      "compensation": 125_000.0
    }
    ```
  </Tab>
</Tabs>

### Outputs

<Tabs>
  <Tab title="Employee Updates">
    ```python theme={null}
    {
      "allocated_shares": 1250.0,         # Total allocated (aggregate)
      "holdings": {                        # Multi-class mode
        "CLASS_A": {
          "shares": 750.0                 # Allocated Class A
        },
        "CLASS_B": {
          "shares": 500.0                 # Allocated Class B
        }
      }
    }
    ```
  </Tab>

  <Tab title="Compliance Events">
    Per employee:

    * `eligibility_evaluated`
    * `compensation_capped` (if over limit)
    * `shares_allocated`
    * `annual_addition_capped` (if over limit)
    * `allocation_computed` (structured event)
  </Tab>
</Tabs>

***

## Compliance Events

<AccordionGroup>
  <Accordion title="eligibility_evaluated" icon="user-check">
    Every employee gets evaluated:

    ```json theme={null}
    {
      "year": 2025,
      "phase": "eligibility",
      "event": "eligibility_evaluated",
      "entity_type": "employee",
      "entity_id": "EMP001",
      "inputs": {
        "age": 35,
        "service_years": 5.0,
        "hours_worked": 2080,
        "eligibility_age": 21,
        "eligibility_service_years": 1.0,
        "eligibility_min_hours": 1000
      },
      "outputs": {
        "eligible": true
      }
    }
    ```
  </Accordion>

  <Accordion title="compensation_capped" icon="scissors">
    When compensation exceeds ERISA limit:

    ```json theme={null}
    {
      "year": 2025,
      "phase": "allocation",
      "event": "compensation_capped",
      "entity_type": "employee",
      "entity_id": "EMP042",
      "details": {
        "original": 400000.0,
        "capped": 345000.0
      },
      "policy": "erisa_compensation_cap"
    }
    ```
  </Accordion>

  <Accordion title="covered_comp_summary" icon="calculator">
    Company-level summary:

    ```json theme={null}
    {
      "year": 2025,
      "phase": "allocation",
      "event": "covered_comp_summary",
      "entity_type": "company",
      "inputs": {
        "max_compensation": 345000.0
      },
      "outputs": {
        "total_capped_compensation": 2875000.0,
        "eligible_employee_count": 45
      }
    }
    ```
  </Accordion>

  <Accordion title="annual_addition_capped" icon="gavel">
    When allocation value exceeds \$69K:

    ```json theme={null}
    {
      "year": 2025,
      "phase": "allocation",
      "event": "annual_addition_capped",
      "entity_type": "employee",
      "entity_id": "EMP105",
      "details": {
        "original_value": 1277500.0,
        "capped_value": 69000.0
      },
      "policy": "erisa_annual_addition_cap"
    }
    ```
  </Accordion>

  <Accordion title="allocation_computed (structured)" icon="file-lines">
    Complete allocation audit trail:

    ```json theme={null}
    {
      "year": 2025,
      "phase": "allocation",
      "event": "allocation_computed",
      "entity_type": "employee",
      "entity_id": "EMP001",
      "inputs": {
        "capped_compensation": 125000.0,
        "total_eligible_compensation": 2875000.0,
        "share_pool_by_security": {
          "CLASS_A": 3000.0,
          "CLASS_B": 2000.0
        },
        "price_by_security": {
          "CLASS_A": 600.0,
          "CLASS_B": 400.0
        },
        "max_annual_addition": 69000.0
      },
      "outputs": {
        "shares_allocated_by_security": {
          "CLASS_A": 130.4,
          "CLASS_B": 86.96
        }
      },
      "policy": "erisa_annual_addition_cap"
    }
    ```
  </Accordion>
</AccordionGroup>

***

## Edge Cases

<AccordionGroup>
  <Accordion title="No Eligible Employees" icon="user-xmark">
    If no employees meet eligibility criteria:

    * Step 3 exits early
    * Share pool **carries forward** to next year
    * No allocations made
  </Accordion>

  <Accordion title="Zero Eligible Compensation" icon="0">
    If all eligible employees have zero compensation:

    * Step 3 exits early
    * Division by zero avoided
    * Share pool carries forward
  </Accordion>

  <Accordion title="Annual Addition Cap Binds for Everyone" icon="lock">
    In high-share-price scenarios:

    * Cap may limit ALL allocations
    * Causes **leftover shares** in pool
    * Leftover shares carry to next year via forfeitures
  </Accordion>

  <Accordion title="Mid-Year Hires" icon="calendar-day">
    Employees hired mid-year:

    * May not meet hours requirement
    * Excluded from allocation
    * Will be eligible next year if they meet criteria
  </Accordion>
</AccordionGroup>

***

## Related Steps

<CardGroup cols={2}>
  <Card title="Step 2: Share Pool" icon="shapes" href="/simulation/step-2-share-pool">
    Provides the shares to allocate
  </Card>

  <Card title="Step 5: Vesting" icon="check-double" href="/simulation/step-5-vesting">
    Determines how much of allocation becomes vested
  </Card>

  <Card title="Plan Rules" icon="gavel" href="/models/plan-rules">
    Eligibility criteria and compliance rules
  </Card>

  <Card title="Employee Model" icon="user" href="/models/overview">
    Employee data structure
  </Card>
</CardGroup>

***

## Summary

Step 3 is the **allocation engine** that:

* ✅ Determines employee eligibility (age, service, hours)
* ✅ Applies ERISA compensation cap (\$345K in 2025)
* ✅ Distributes shares pro-rata by eligible compensation
* ✅ Enforces annual addition cap (\$69K in 2025)
* ✅ Supports multi-class securities with per-security tracking
* ✅ Emits comprehensive compliance events

**Key Insight:** ERISA caps can **significantly constrain** allocations for highly compensated employees and high-share-price companies, often causing shares to remain unallocated and carry forward to future years.
