The ESOPTrust is the central accounting hub for all plan assets and liabilities. It represents the legal entity that holds company stock and cash on behalf of plan participants.
New in v0.2: Enhanced multi-loan support with dedicated suspense share tracking per loan!
All ESOP assets are owned by the trust, not by individual participants directly. The trust allocates shares and cash to individual participant accounts according to plan rules.
Shares are categorized by their allocation status:
Copy
Ask AI
# Shares credited to individual participant accountstrust.allocated_shares = 45_000# Shares owned by trust but not yet allocatedtrust.unallocated_shares = 5_000# Shares held as collateral for loans (in suspense)trust.total_suspense_shares() = 30_000 # Sum across all loans# Total shares must always balanceassert trust.total_shares_outstanding == ( trust.allocated_shares + trust.unallocated_shares + trust.total_suspense_shares()) # 45,000 + 5,000 + 30,000 = 80,000 ✓
Share Conservation Law: Total shares must always equal the sum of allocated, unallocated, and suspense shares. The engine validates this after every processing step.
ESOP Loans
The trust can have multiple loans, each with dedicated suspense shares:
Copy
Ask AI
trust.loans = [ ESOPLoan( loan_id="LOAN_2020", principal_balance=1_500_000, interest_rate=0.065, suspense_shares=15_000 ), ESOPLoan( loan_id="LOAN_2023", principal_balance=1_200_000, interest_rate=0.070, suspense_shares=15_000 )]# Total suspense shares across all loanstotal_suspense = trust.total_suspense_shares() # 30,000
# Total suspense shares across all loansdef total_suspense_shares(self) -> Decimal: return sum(loan.suspense_shares for loan in self.loans)# Total market value of trust assetsdef total_asset_value(self) -> Decimal: share_value = self.total_shares_outstanding * self.current_share_price cash_value = self.cash_ledger.total_cash() return share_value + cash_value# Shares available for immediate allocationdef allocable_share_pool(self) -> Decimal: return self.unallocated_shares