Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 31 additions & 8 deletions Test/daml/OpenCapTable/TestIssuerAuthorizedSharesAdjustment.daml
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,21 @@ mkIssuer issuer system_operator ctx =
initial_shares_authorized = Some (OcfInitialSharesNumeric 1000.0)
comments = []

issuerAuthorizedSharesAdjustment : Text -> Text -> Decimal -> IssuerAuthorizedSharesAdjustmentOcfData
issuerAuthorizedSharesAdjustment adjustmentId issuerId sharesAuthorized =
IssuerAuthorizedSharesAdjustmentOcfData with
id = adjustmentId
date = DT.time (DA.date 2024 Jan 01) 0 0 0
issuer_id = issuerId
new_shares_authorized = sharesAuthorized
board_approval_date = None
stockholder_approval_date = None
comments = []

createIssuerAuthorizedSharesAdjustment issuer capTableCid =
submit issuer do
exerciseCmd capTableCid CT.UpdateCapTable with
creates = [CT.OcfCreateIssuerAuthorizedSharesAdjustment IssuerAuthorizedSharesAdjustmentOcfData with
id = "TX_ISSUER_AUTH_SHARES_ADJ_1"
date = DT.time (DA.date 2024 Jan 01) 0 0 0
issuer_id = "ISSUER_1"
new_shares_authorized = 2000.0
board_approval_date = None
stockholder_approval_date = None
comments = []]
creates = [CT.OcfCreateIssuerAuthorizedSharesAdjustment (issuerAuthorizedSharesAdjustment "TX_ISSUER_AUTH_SHARES_ADJ_1" "ISSUER_1" 2000.0)]
edits = []
deletes = []

Expand Down Expand Up @@ -68,3 +72,22 @@ testIssuerAuthorizedSharesAdjustment_OptionalsSome = script do
edits = []
deletes = []
pure ()

testIssuerAuthorizedSharesAdjustment_WrongIssuerIdCreateFails = script do
TestOcp{issuer, cap_table} <- setupTestOcp

submitMustFail issuer do
exerciseCmd cap_table CT.UpdateCapTable with
creates = [CT.OcfCreateIssuerAuthorizedSharesAdjustment (issuerAuthorizedSharesAdjustment "TX_BAD_ISSUER_ID" "OTHER_ISSUER" 2000.0)]
edits = []
deletes = []

testIssuerAuthorizedSharesAdjustment_WrongIssuerIdEditFails = script do
TestOcp{issuer, cap_table} <- setupTestOcp
result <- createIssuerAuthorizedSharesAdjustment issuer cap_table

submitMustFail issuer do
exerciseCmd result.updatedCapTableCid CT.UpdateCapTable with
creates = []
edits = [CT.OcfEditIssuerAuthorizedSharesAdjustment (issuerAuthorizedSharesAdjustment "TX_ISSUER_AUTH_SHARES_ADJ_1" "OTHER_ISSUER" 2000.0)]
deletes = []
4 changes: 2 additions & 2 deletions dars/OpenCapTable-v34/0.0.2/OpenCapTable-v34.dar
Git LFS file not shown
4 changes: 2 additions & 2 deletions dars/dars.lock
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
]
},
"OpenCapTable-v34/0.0.2/OpenCapTable-v34.dar": {
"sha256": "2afe248b351f9b4e7b84bf2b23d6c5d8d20308126de6c694ab95d21490b0d82b",
"size": 2466418,
"sha256": "1ae8fcf22319a4c408ac0a451bbd40127f4d58c33c1aa11d3849b2550226d34a",
"size": 2467970,
"sdkVersion": "3.4.10",
"uploadedAt": "2026-07-07T21:50:59.634Z",
"networks": []
Expand Down
2 changes: 2 additions & 0 deletions scripts/codegen/generate-captable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ interface TypeDef {
validates_stock_class_initial_authorized_shares: boolean;
validates_stock_class_authorized_adjustment: boolean;
validates_stock_issuance_authorized_shares: boolean;
validates_issuer_id_reference: boolean;
// For issuance types, the name of the security_id index map (e.g., 'stock_issuances_by_security_id')
security_id_index_map: string | null;
}
Expand Down Expand Up @@ -236,6 +237,7 @@ function discoverTypes(config: Config): TypeDef[] {
validates_stock_class_initial_authorized_shares: name === 'StockClass',
validates_stock_class_authorized_adjustment: name === 'StockClassAuthorizedSharesAdjustment',
validates_stock_issuance_authorized_shares: name === 'StockIssuance',
validates_issuer_id_reference: name === 'IssuerAuthorizedSharesAdjustment',
security_id_index_map: SECURITY_ID_INDEX_MAPS[name] ?? null,
};

Expand Down
19 changes: 13 additions & 6 deletions scripts/codegen/templates/CapTable.daml.template
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,13 @@ validateCurrentStockClassAuthorizedShares maps stockClassId excludedAdjustmentId
limitOpt <- currentStockClassAuthorizedLimit maps stockClassId excludedAdjustmentId stockClassOverride additionalAdjustment
assertWithinStockClassAuthorizedShares stockClassId currentIssued limitOpt

validateIssuerReference : ContractId Issuer -> Text -> Update ()
validateIssuerReference issuerCid issuerId = do
issuerContract <- fetch issuerCid
assertMsg
("Issuer ID mismatch: " <> issuerId <> " does not match cap table issuer " <> issuerContract.issuer_data.id)
(issuerId == issuerContract.issuer_data.id)

-- | Get the processing tier for a create operation
getCreateTier : OcfCreateData -> Int
getCreateTier createData = case createData of
Expand All @@ -212,16 +219,16 @@ getCreateTier createData = case createData of
{{/each}}

-- | Process a single create operation, returning updated maps and the created ContractId
processCreate : Context -> CapTableMaps -> OcfCreateData -> Update (CapTableMaps, OcfContractId)
processCreate ctx maps createData = case createData of
processCreate : Context -> ContractId Issuer -> CapTableMaps -> OcfCreateData -> Update (CapTableMaps, OcfContractId)
processCreate ctx issuerCid maps createData = case createData of
{{#each types_tier}}
{{> create-case}}
{{/each}}

-- | Process a single edit operation, returning updated maps and the edited ContractId
-- Note: OcfEditIssuer is handled separately in UpdateCapTable since issuer is not a map
processEdit : Context -> CapTableMaps -> OcfEditData -> Update (CapTableMaps, OcfContractId)
processEdit ctx maps editData = case editData of
processEdit : Context -> ContractId Issuer -> CapTableMaps -> OcfEditData -> Update (CapTableMaps, OcfContractId)
processEdit ctx issuerCid maps editData = case editData of
OcfEditIssuer _ -> error "OcfEditIssuer should be handled separately in UpdateCapTable"
{{#each types_alpha}}
{{> edit-case}}
Expand Down Expand Up @@ -305,7 +312,7 @@ template CapTable
-- Process regular edits (map-based entities)
(mapsAfterEdits, regularEditedCids) <- foldlA
(\(maps, cids) editData -> do
(newMaps, cid) <- processEdit context maps editData
(newMaps, cid) <- processEdit context issuer maps editData
pure (newMaps, cids ++ [cid]))
(mapsAfterDeletes, [])
regularEdits
Expand All @@ -332,7 +339,7 @@ template CapTable
-- Process creates last (after deletes freed constraints)
(finalMaps, createdCids) <- foldlA
(\(maps, cids) createData -> do
(newMaps, cid) <- processCreate context maps createData
(newMaps, cid) <- processCreate context newIssuerCid maps createData
pure (newMaps, cids ++ [cid]))
(mapsAfterEdits, [])
sortedCreates
Expand Down
3 changes: 3 additions & 0 deletions scripts/codegen/templates/loops/create-case.daml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ OcfCreate{{name}} d -> do
{{/if}}
{{#if validates_stock_class_authorized_adjustment}}
validateCurrentStockClassAuthorizedShares maps d.stock_class_id None None (Some d)
{{/if}}
{{#if validates_issuer_id_reference}}
validateIssuerReference issuerCid d.issuer_id
{{/if}}
cid <- create {{name}} with context = ctx, {{data_param}} = d
{{#if security_id_index_map}}
Expand Down
3 changes: 3 additions & 0 deletions scripts/codegen/templates/loops/edit-case.daml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ OcfEdit{{name}} d -> do
validateCurrentStockClassAuthorizedShares maps oldAdjustment.{{data_param}}.stock_class_id (Some oldAdjustment.{{data_param}}.id) None (Some d)
validateCurrentStockClassAuthorizedShares maps d.stock_class_id (Some oldAdjustment.{{data_param}}.id) None (Some d)
{{/if}}
{{#if validates_issuer_id_reference}}
validateIssuerReference issuerCid d.issuer_id
{{/if}}
{{#if security_id_index_map}}
-- Fetch old contract to get old security_id for index map cleanup
oldContract <- fetch oldCid
Expand Down
Loading