Open-Cap-Table-Coalition/ocx

Handle multiple Stock Class Conversion Rights for preferred stock classes

pjohnmeyer opened this issue · 4 comments

In v0.4 of the OCX sample spreadsheet, the conversion ratio for a stock class appears on the Context sheet, which is used on the Stakeholder Snapshot sheet to calculated "as converted" numbers.

In v1.0.0 of the OCF specification, however, every stock class can have more than one possible "StockClassConversionRight", each of which can have its own separate ratio. Note that this is a list:

image

Desired Outcome

Per discussion with members of the Law Firm Working Group, the "normal" case is that each Preferred Stock Class will convert to a particular Common Stock Class with 1 vote per share as the "underlying" instrument for everything. There are other arrangements, of course, so we agreed the algorithm should be something like this:

  1. If only one StockClassConversionRight converts to a common stock class, use that one's ratio
  2. If more than one StockClassConversionRight converts to different common stock classes, choose the conversion ratio that corresponds with the common stock class with the lowest non-zero votes per share.
  3. If there are no conversions to common, but there are conversion to another preferred stock class, recursively continue to apply steps 1 and 2 until a single common stock class is found -- multiplying all of the multipliers along the way.
  4. ERROR otherwise

These rules only apply, however, if the StockClassConversionRight converts_to_stock_class_id -- if it converts_to_future_round we have no information on the target class. Classes that converts_to_future_round can have a ratio with no target common or preferred class to implement this against, so there are more questions to answer here -- or improvements to be made to OCF.

To-Do

  • If necessary, determine necessary in-tool calculations and document for review and approval, if necessary
  • ocf-package: Are the necessary OCF Files being processed?
  • model: Are the necessary OCF Objects being consumed?
  • Develop workbook against Model interfaces.
  • Implement actual Model
  • Integrate and test end-to-end

Some examples based on the Desired Outcome:

Preferred -> Preferred -> Common chaining

If Preferred A converts to Preferred B at 2x, and Preferred B converts to Common at 3x, then the conversion ratios compound:

2.0000 * 3.0000 = 6.000

Preferred to multiple Commons

If Preferred A, depending on circumstances:

  • Converts to Common Class A at 3x, with 1 vote per share, or
  • Converts to Common Class B at 10x, with 0 votes per share

then for OCX we select the 3x multiplier because Class B has 0 votes per share.

If, however, we change Class B to have 0.5 votes per share, then for OCX we would select its 10x multiplier because it is the lowest non-zero votes per share.

Complex hierarchy

OCF currently supports some highly complex, if unlikely scenarios. OCX has to assume these scenarios are possible to at least some degree. So, in the unlikely case that we have a very complex hierarchy of conversions, we will use breadth first search to find the conversion ratio. If at any depth of search we find even one candidate target Common class, we will stop analysis. To illustrate:

flowchart TD
    subgraph Depth 0
        PrA[Preferred A]
    end
    
    subgraph Depth 1
        PrB[Preferred B]
        PrD[Preferred D]
    end
    
    PrA -->|Converts at 2x| PrB
    PrA -->|Converts at 3x| PrD

    subgraph Depth 2
        PrC[Preferred C]
        CoX[Common X: 2 votes]
        CoY[Common Y: 3 votes]
    end

    PrB -->|Converts at 2x| PrC
    PrD -->|Converts at 1x| CoY
    PrD -->|Converts at 1.5x| CoX

    subgraph Depth3
        CoZ[Common Z: 1 vote]
    end
    PrC -->|Converts at 2x| CoZ    

If we were to do a full depth exhaustive search of all possibilities and apply the rules in this issue, the "winning" path would be Preferred A --2x--> Preferred B --2x--> Preferred C --2x--> Common Z for a conversion ratio of 2 * 2 * 2 = 8, because Common Z has the lowest non-zero votes per share at 1.

I am proposing that the correct initial implementation is to apply Rules 1 and 2 with the shortest path possible, so the "winning" path would occur at Depth 2 -- the first depth with one or more Common stocks. Since Common X has the lower votes per share, the path would be Preferred A --3x--> Preferred D --1.5x--> Common X for a conversion ratio of 3 * 1.5 = 4.5.

Other tie-breaking scenarios

If two common classes at the same depth have the same number of votes per share, I would suggest that we choose the common class with the highest total conversion ratio, assuming the most advantageous position for the shareholder. That tie-breaker could be reversed, or replaced with some other feature like board approval dates.

JSv4 commented

Thanks for this super thoughtful question @pjohnmeyer.

Our initial take is, starting with given series of preferred stock, you'd want to recursively traverse the tree to the lowest non-zero common class / series it can convert into (with the caveat that this is a heuristic and the important thing here is to document the rules and show your work (as you noted). So, given Preferred A, we think you'd want to convert into Common Z. If, however, you started with Preferred D, then you'd want to find your way to Common X. Would be good to hear from others on this.

To summarize, here are the different case scenarios we can work against:

  • converts_to_stock_class_id is null
  • converts_to_future_round is true (it raises questions like: can converts_to_stock_class_id and converts_to_future_round be null simultaneously? Which property has the highest priority?)
  • we have one StockClassConversionRight that converts to a common stock class
  • we have 2 or more StockClassConversionRights that convert to different common stock classes
  • we have 2 or more StockClassConversionRights that convert to different common and preferred stock classes

cc @pjohnmeyer

Sounds like a good progression. I think on some of this we can make some assumptions, as long as we "show our work" as John says. So some thoughts:

For the purposes of calculating a ratio, this algorithm only cares about converts_to_stock_class_id, so it should take precedence. @JSv4 I added this note to the wiki but I didn't create an issue yet; not sure we want to create 2.x only issues yet?

If there are no conversion pathways that reach an actual common stock then we can error out and not handle that case.

We will ultimately also want code for generating a text description of the conversion so we can add that to the "Notes" on the spreadsheet -- for now we could just Log it -- explaining the conversion, e.g. using John's two examples.

Converted from Preferred A > Preferred B > Preferred C > Common Z at 8.0000

or

Converted from Preferred D > Common X at 1.5000

The full algorithm will probably need to be described in the documentation, I don't think we'll be able to spell it all out in the Excel output without being obnoxious.