CorporateAction¶
Calls¶
change_record_date¶
Changes the record date of the CA identified by ca_id.
## Arguments
- origin which must be an external agent of ca_id.ticker with relevant permissions.
- ca_id of the CA to alter.
- record_date, if any, to calculate the impact of the CA.
If provided, this results in a scheduled balance snapshot ("checkpoint") at the date.
# Errors
- UnauthorizedAgent if origin is not agent-permissioned for ticker.
- NoSuchCA if id does not identify an existing CA.
- When record_date.is_some(), other errors due to checkpoint scheduling may occur.
# Permissions * Asset
Attributes¶
| Name | Type |
|---|---|
| ca_id | CAId |
| record_date | Option<RecordDateSpec> |
Python¶
call = substrate.compose_call(
'CorporateAction', 'change_record_date', {
'ca_id': {
'local_id': 'u32',
'ticker': '[u8; 12]',
},
'record_date': (
None,
{
'Existing': 'u64',
'ExistingSchedule': 'u64',
'Scheduled': 'u64',
},
),
}
)
initiate_corporate_action¶
Initiates a CA for ticker of kind with details and other provided arguments.
## Arguments
- origin which must be an external agent of ticker with relevant permissions.
- ticker that the CA is made for.
- kind of CA being initiated.
- decl_date of CA bring initialized.
- record_date, if any, to calculate the impact of this CA.
If provided, this results in a scheduled balance snapshot ("checkpoint") at the date.
- details of the CA in free-text form, up to a certain number of bytes in length.
- targets, if any, which this CA is relevant/irrelevant to.
Overrides, if provided, the default at the asset level (set_default_targets).
- default_withholding_tax, if any, is the default withholding tax to use for this CA.
Overrides, if provided, the default at the asset level (set_default_withholding_tax).
- withholding_tax, if any, provides per-DID withholding tax overrides.
Overrides, if provided, the default at the asset level (set_did_withholding_tax).
# Errors
- DetailsTooLong if details.len() goes beyond max_details_length.
- UnauthorizedAgent if origin is not agent-permissioned for ticker.
- CounterOverflow in the unlikely event that so many CAs were created for this ticker,
that integer overflow would have occured if instead allowed.
- TooManyDidTaxes if withholding_tax.unwrap().len() would go over the limit MaxDidWhts.
- DuplicateDidTax if a DID is included more than once in wt.
- TooManyTargetIds if targets.unwrap().identities.len() > T::MaxTargetIds::get().
- DeclDateInFuture if the declaration date is not in the past.
- When record_date.is_some(), other errors due to checkpoint scheduling may occur.
# Permissions * Asset
Attributes¶
| Name | Type |
|---|---|
| ticker | Ticker |
| kind | CAKind |
| decl_date | Moment |
| record_date | Option<RecordDateSpec> |
| details | CADetails |
| targets | Option<TargetIdentities> |
| default_withholding_tax | Option<Tax> |
| withholding_tax | Option<Vec<(IdentityId, Tax)>> |
Python¶
call = substrate.compose_call(
'CorporateAction', 'initiate_corporate_action', {
'decl_date': 'u64',
'default_withholding_tax': (
None,
'u32',
),
'details': 'Bytes',
'kind': (
'PredictableBenefit',
'UnpredictableBenefit',
'IssuerNotice',
'Reorganization',
'Other',
),
'record_date': (
None,
{
'Existing': 'u64',
'ExistingSchedule': 'u64',
'Scheduled': 'u64',
},
),
'targets': (
None,
{
'identities': ['[u8; 32]'],
'treatment': (
'Include',
'Exclude',
),
},
),
'ticker': '[u8; 12]',
'withholding_tax': (
None,
[('[u8; 32]', 'u32')],
),
}
)
initiate_corporate_action_and_distribute¶
Utility extrinsic to batch initiate_corporate_action and distribute
Attributes¶
| Name | Type |
|---|---|
| ca_args | InitiateCorporateActionArgs |
| portfolio | Option<PortfolioNumber> |
| currency | Ticker |
| per_share | Balance |
| amount | Balance |
| payment_at | Moment |
| expires_at | Option<Moment> |
Python¶
call = substrate.compose_call(
'CorporateAction', 'initiate_corporate_action_and_distribute', {
'amount': 'u128',
'ca_args': {
'decl_date': 'u64',
'default_withholding_tax': (
None,
'u32',
),
'details': 'Bytes',
'kind': (
'PredictableBenefit',
'UnpredictableBenefit',
'IssuerNotice',
'Reorganization',
'Other',
),
'record_date': (
None,
{
'Existing': 'u64',
'ExistingSchedule': 'u64',
'Scheduled': 'u64',
},
),
'targets': (
None,
{
'identities': [
'[u8; 32]',
],
'treatment': (
'Include',
'Exclude',
),
},
),
'ticker': '[u8; 12]',
'withholding_tax': (
None,
[('[u8; 32]', 'u32')],
),
},
'currency': '[u8; 12]',
'expires_at': (None, 'u64'),
'payment_at': 'u64',
'per_share': 'u128',
'portfolio': (None, 'u64'),
}
)
link_ca_doc¶
Link the given CA id to the given docs.
Any previous links for the CA are removed in favor of docs.
The workflow here is to add the documents and initiating the CA in any order desired. Once both exist, they can now be linked together.
## Arguments
- origin which must be an external agent of id.ticker with relevant permissions.
- id of the CA to associate with docs.
- docs to associate with the CA with id.
# Errors
- UnauthorizedAgent if origin is not agent-permissioned for ticker.
- NoSuchCA if id does not identify an existing CA.
- NoSuchDoc if any of docs does not identify an existing document.
# Permissions * Asset
Attributes¶
| Name | Type |
|---|---|
| id | CAId |
| docs | Vec<DocumentId> |
Python¶
call = substrate.compose_call(
'CorporateAction', 'link_ca_doc', {
'docs': ['u32'],
'id': {
'local_id': 'u32',
'ticker': '[u8; 12]',
},
}
)
remove_ca¶
Removes the CA identified by ca_id.
Associated data, such as document links, ballots, and capital distributions are also removed.
Any schedule associated with the record date will see
strong_ref_count(schedule_id) decremented.
## Arguments
- origin which must be an external agent of ca_id.ticker with relevant permissions.
- ca_id of the CA to remove.
# Errors
- UnauthorizedAgent if origin is not agent-permissioned for ticker.
- NoSuchCA if id does not identify an existing CA.
# Permissions * Asset
Attributes¶
| Name | Type |
|---|---|
| ca_id | CAId |
Python¶
call = substrate.compose_call(
'CorporateAction', 'remove_ca', {
'ca_id': {
'local_id': 'u32',
'ticker': '[u8; 12]',
},
}
)
set_default_targets¶
Set the default CA TargetIdentities to targets.
## Arguments
- origin which must be an external agent of ticker with relevant permissions.
- ticker for which the default identities are changing.
- targets the default target identities for a CA.
## Errors
- UnauthorizedAgent if origin is not agent-permissioned for ticker.
- TooManyTargetIds if targets.identities.len() > T::MaxTargetIds::get().
# Permissions * Asset
Attributes¶
| Name | Type |
|---|---|
| ticker | Ticker |
| targets | TargetIdentities |
Python¶
call = substrate.compose_call(
'CorporateAction', 'set_default_targets', {
'targets': {
'identities': ['[u8; 32]'],
'treatment': (
'Include',
'Exclude',
),
},
'ticker': '[u8; 12]',
}
)
set_default_withholding_tax¶
Set the default withholding tax for all DIDs and CAs relevant to this ticker.
## Arguments
- origin which must be an external agent of ticker with relevant permissions.
- ticker that the withholding tax will apply to.
- tax that should be withheld when distributing dividends, etc.
## Errors
- UnauthorizedAgent if origin is not agent-permissioned for ticker.
# Permissions * Asset
Attributes¶
| Name | Type |
|---|---|
| ticker | Ticker |
| tax | Tax |
Python¶
call = substrate.compose_call(
'CorporateAction', 'set_default_withholding_tax', {'tax': 'u32', 'ticker': '[u8; 12]'}
)
set_did_withholding_tax¶
Set the withholding tax of ticker for taxed_did to tax.
If Some(tax), this overrides the default withholding tax of ticker to tax for taxed_did.
Otherwise, if None, the default withholding tax will be used.
## Arguments
- origin which must be an external agent of ticker with relevant permissions.
- ticker that the withholding tax will apply to.
- taxed_did that will have its withholding tax updated.
- tax that should be withheld when distributing dividends, etc.
## Errors
- UnauthorizedAgent if origin is not agent-permissioned for ticker.
- TooManyDidTaxes if Some(tax) and adding the override would go over the limit MaxDidWhts.
# Permissions * Asset
Attributes¶
| Name | Type |
|---|---|
| ticker | Ticker |
| taxed_did | IdentityId |
| tax | Option<Tax> |
Python¶
call = substrate.compose_call(
'CorporateAction', 'set_did_withholding_tax', {
'tax': (None, 'u32'),
'taxed_did': '[u8; 32]',
'ticker': '[u8; 12]',
}
)
set_max_details_length¶
Set the max length of details in terms of bytes.
May only be called via a PIP.
Attributes¶
| Name | Type |
|---|---|
| length | u32 |
Python¶
call = substrate.compose_call(
'CorporateAction', 'set_max_details_length', {'length': 'u32'}
)
Events¶
CAInitiated¶
A CA was initiated. (Agent DID, CA id, the CA, the CA details)
Attributes¶
| Name | Type | Composition |
|---|---|---|
| None | EventDid |
[u8; 32] |
| None | CAId |
{'ticker': '[u8; 12]', 'local_id': 'u32'} |
| None | CorporateAction |
{'kind': ('PredictableBenefit', 'UnpredictableBenefit', 'IssuerNotice', 'Reorganization', 'Other'), 'decl_date': 'u64', 'record_date': (None, {'date': 'u64', 'checkpoint': {'Scheduled': ('u64', 'u64'), 'Existing': 'u64'}}), 'targets': {'identities': ['[u8; 32]'], 'treatment': ('Include', 'Exclude')}, 'default_withholding_tax': 'u32', 'withholding_tax': [('[u8; 32]', 'u32')]} |
| None | CADetails |
Bytes |
CALinkedToDoc¶
A CA was linked to a set of docs. (Agent DID, CA Id, List of doc identifiers)
Attributes¶
| Name | Type | Composition |
|---|---|---|
| None | IdentityId |
[u8; 32] |
| None | CAId |
{'ticker': '[u8; 12]', 'local_id': 'u32'} |
| None | Vec<DocumentId> |
['u32'] |
CARemoved¶
A CA was removed. (Agent DID, CA Id)
Attributes¶
| Name | Type | Composition |
|---|---|---|
| None | EventDid |
[u8; 32] |
| None | CAId |
{'ticker': '[u8; 12]', 'local_id': 'u32'} |
DefaultTargetIdentitiesChanged¶
The set of default TargetIdentities for a ticker changed.
(Agent DID, Ticker, New TargetIdentities)
Attributes¶
| Name | Type | Composition |
|---|---|---|
| None | IdentityId |
[u8; 32] |
| None | Ticker |
[u8; 12] |
| None | TargetIdentities |
{'identities': ['[u8; 32]'], 'treatment': ('Include', 'Exclude')} |
DefaultWithholdingTaxChanged¶
The default withholding tax for a ticker changed. (Agent DID, Ticker, New Tax).
Attributes¶
| Name | Type | Composition |
|---|---|---|
| None | IdentityId |
[u8; 32] |
| None | Ticker |
[u8; 12] |
| None | Tax |
u32 |
DidWithholdingTaxChanged¶
The withholding tax specific to a DID for a ticker changed. (Agent DID, Ticker, Taxed DID, New Tax).
Attributes¶
| Name | Type | Composition |
|---|---|---|
| None | IdentityId |
[u8; 32] |
| None | Ticker |
[u8; 12] |
| None | IdentityId |
[u8; 32] |
| None | Option<Tax> |
(None, 'u32') |
MaxDetailsLengthChanged¶
The maximum length of details in bytes was changed.
(GC DID, new length)
Attributes¶
| Name | Type | Composition |
|---|---|---|
| None | IdentityId |
[u8; 32] |
| None | u32 |
u32 |
RecordDateChanged¶
A CA's record date changed.
Attributes¶
| Name | Type | Composition |
|---|---|---|
| None | EventDid |
[u8; 32] |
| None | CAId |
{'ticker': '[u8; 12]', 'local_id': 'u32'} |
| None | CorporateAction |
{'kind': ('PredictableBenefit', 'UnpredictableBenefit', 'IssuerNotice', 'Reorganization', 'Other'), 'decl_date': 'u64', 'record_date': (None, {'date': 'u64', 'checkpoint': {'Scheduled': ('u64', 'u64'), 'Existing': 'u64'}}), 'targets': {'identities': ['[u8; 32]'], 'treatment': ('Include', 'Exclude')}, 'default_withholding_tax': 'u32', 'withholding_tax': [('[u8; 32]', 'u32')]} |
Storage functions¶
CADocLink¶
Associations from CAs to Documents via their IDs.
(CAId => [DocumentId])
The CorporateActions map stores Ticker => LocalId => The CA,
so we can infer Ticker => CAId. Therefore, we don't need a double map.
Python¶
result = substrate.query(
'CorporateAction', 'CADocLink', [
{
'local_id': 'u32',
'ticker': '[u8; 12]',
},
]
)
Return value¶
['u32']
CAIdSequence¶
The next per-Ticker CA ID in the sequence.
The full ID is defined as a combination of Ticker and a number in this sequence.
Python¶
result = substrate.query(
'CorporateAction', 'CAIdSequence', ['[u8; 12]']
)
Return value¶
'u32'
CorporateActions¶
All recorded CAs thus far.
Only generic information is stored here.
Specific CAKinds, e.g., benefits and corporate ballots, may use additional on-chain storage.
(ticker => local ID => the corporate action)
Python¶
result = substrate.query(
'CorporateAction', 'CorporateActions', ['[u8; 12]', 'u32']
)
Return value¶
{
'decl_date': 'u64',
'default_withholding_tax': 'u32',
'kind': (
'PredictableBenefit',
'UnpredictableBenefit',
'IssuerNotice',
'Reorganization',
'Other',
),
'record_date': (
None,
{'checkpoint': {'Existing': 'u64', 'Scheduled': ('u64', 'u64')}, 'date': 'u64'},
),
'targets': {
'identities': ['[u8; 32]'],
'treatment': ('Include', 'Exclude'),
},
'withholding_tax': [('[u8; 32]', 'u32')],
}
DefaultTargetIdentities¶
The identities targeted by default for CAs for this ticker, either to be excluded or included.
(ticker => target identities)
Python¶
result = substrate.query(
'CorporateAction', 'DefaultTargetIdentities', ['[u8; 12]']
)
Return value¶
{'identities': ['[u8; 32]'], 'treatment': ('Include', 'Exclude')}
DefaultWithholdingTax¶
The default amount of tax to withhold ("withholding tax", WT) for this ticker when distributing dividends.
To understand withholding tax, e.g., let's assume that you hold ACME shares. ACME now decides to distribute 100 SEK to Alice. Alice lives in Sweden, so Skatteverket (the Swedish tax authority) wants 30% of that. Then those 100 * 30% are withheld from Alice, and ACME will send them to Skatteverket.
(ticker => % to withhold)
Python¶
result = substrate.query(
'CorporateAction', 'DefaultWithholdingTax', ['[u8; 12]']
)
Return value¶
'u32'
Details¶
Associates details in free-form text with a CA by its ID. (CAId => CADetails)
Python¶
result = substrate.query(
'CorporateAction', 'Details', [
{
'local_id': 'u32',
'ticker': '[u8; 12]',
},
]
)
Return value¶
'Bytes'
DidWithholdingTax¶
The amount of tax to withhold ("withholding tax", WT) for a certain ticker x DID.
If an entry exists for a certain DID, it overrides the default in DefaultWithholdingTax.
(ticker => [(did, % to withhold)]
Python¶
result = substrate.query(
'CorporateAction', 'DidWithholdingTax', ['[u8; 12]']
)
Return value¶
[('[u8; 32]', 'u32')]
MaxDetailsLength¶
Determines the maximum number of bytes that the free-form details of a CA can store.
Note that this is not the number of chars or the number of graphemes.
While this may be unnatural in terms of human understanding of a text's length,
it more closely reflects actual storage costs ('a' is cheaper to store than an emoji).
Python¶
result = substrate.query(
'CorporateAction', 'MaxDetailsLength', []
)
Return value¶
'u32'
StorageVersion¶
Storage version.
Python¶
result = substrate.query(
'CorporateAction', 'StorageVersion', []
)
Return value¶
'u8'
Constants¶
MaxDidWhts¶
Value¶
1000
Python¶
constant = substrate.get_constant('CorporateAction', 'MaxDidWhts')
MaxTargetIds¶
Value¶
1000
Python¶
constant = substrate.get_constant('CorporateAction', 'MaxTargetIds')
Errors¶
DeclDateAfterRecordDate¶
A CA's declaration date was strictly after its record date.
DeclDateInFuture¶
A CA's declaration date occurs in the future.
DetailsTooLong¶
The details of a CA exceeded the max allowed length.
DuplicateDidTax¶
A withholding tax override for a given DID was specified more than once. The chain refused to make a choice, and hence there was an error.
NoRecordDate¶
The CA did not have a record date.
NoSuchCA¶
A CA with the given CAId did not exist.
NoSuchCheckpointId¶
On CA creation, a checkpoint ID was provided which doesn't exist.
NotTargetedByCA¶
CA does not target the DID.
RecordDateAfterStart¶
A CA's record date was strictly after the "start" time, where "start" is context dependent. For example, it could be the start of a ballot, or the start-of-payment in capital distribution.
TooManyDidTaxes¶
Too many withholding tax overrides were specified.
TooManyTargetIds¶
Too many identities in TargetIdentities were specified.