Skip to content

PoolSystem


Calls


close_epoch

Close the current epoch

Closing an epoch locks in all invest and redeem orders placed during the epoch, and causes all further invest and redeem orders to be set for the next epoch.

If all orders can be executed without violating any pool constraints - which include maximum reserve and the tranche risk buffers - the execution will also be done. See execute_epoch for details on epoch execution.

If pool constraints would be violated by executing all orders, the pool enters a submission period. During a submission period, partial executions can be submitted to be scored, and the best-scoring solution will eventually be executed. See submit_solution.

Attributes

Name Type
pool_id T::PoolId

Python

call = substrate.compose_call(
    'PoolSystem', 'close_epoch', {'pool_id': 'u64'}
)

execute_epoch

Execute an epoch for which a valid solution has been submitted.

  • Mints or burns tranche tokens based on investments and redemptions
  • Updates the portion of the reserve and loan balance assigned to each tranche, based on the investments and redemptions to those tranches.

Attributes

Name Type
pool_id T::PoolId

Python

call = substrate.compose_call(
    'PoolSystem', 'execute_epoch', {'pool_id': 'u64'}
)

set_max_reserve

Sets the maximum reserve for a pool

The caller must have the LiquidityAdmin role in order to invoke this extrinsic. This role is not given to the pool creator by default, and must be added with the Permissions pallet before this extrinsic can be called.

Attributes

Name Type
pool_id T::PoolId
max_reserve T::Balance

Python

call = substrate.compose_call(
    'PoolSystem', 'set_max_reserve', {
    'max_reserve': 'u128',
    'pool_id': 'u64',
}
)

submit_solution

Submit a partial execution solution for a closed epoch

If the submitted solution is "better" than the previous best solution, it will replace it. Solutions are ordered such that solutions which do not violate constraints are better than those that do.

Once a valid solution has been submitted, the challenge time begins. The pool can be executed once the challenge time has expired.

Attributes

Name Type
pool_id T::PoolId
solution Vec<TrancheSolution>

Python

call = substrate.compose_call(
    'PoolSystem', 'submit_solution', {
    'pool_id': 'u64',
    'solution': [
        {
            'invest_fulfillment': 'u64',
            'redeem_fulfillment': 'u64',
        },
    ],
}
)

Events


Created

A pool was created.

Attributes

Name Type Composition
admin T::AccountId AccountId
depositor T::AccountId AccountId
pool_id T::PoolId u64
essence PoolEssenceOf<T> {'currency': {'Native': None, 'Tranche': ('u64', '[u8; 16]'), None: None, 'AUSD': None, 'ForeignAsset': 'u32', 'Staking': ('BlockRewards',), 'LocalAsset': 'u32'}, 'max_reserve': 'u128', 'max_nav_age': 'u64', 'min_epoch_time': 'u64', 'tranches': [{'currency': {'pool_id': 'u64', 'tranche_id': '[u8; 16]'}, 'ty': {'Residual': None, 'NonResidual': {'interest_rate_per_sec': 'u128', 'min_risk_buffer': 'u64'}}, 'metadata': {'token_name': 'Bytes', 'token_symbol': 'Bytes'}}]}

EpochClosed

An epoch was closed.

Attributes

Name Type Composition
pool_id T::PoolId u64
epoch_id T::EpochId u32

EpochExecuted

An epoch was executed.

Attributes

Name Type Composition
pool_id T::PoolId u64
epoch_id T::EpochId u32

MaxReserveSet

The max reserve was updated.

Attributes

Name Type Composition
pool_id T::PoolId u64

NegativeBalanceSheet

The PoolFeesNAV exceeds the sum of the AUM and the total reserve of the pool

Attributes

Name Type Composition
pool_id T::PoolId u64
nav_aum T::Balance u128
nav_fees T::Balance u128
reserve T::Balance u128

ProposedChange

A change was proposed.

Attributes

Name Type Composition
pool_id T::PoolId u64
change_id T::Hash scale_info::12
change T::RuntimeChange {'Loans': {'Loan': ('u64', {'Maturity': {'Fixed': 'InnerStruct'}, 'MaturityExtension': 'u64', 'InterestRate': {'Fixed': 'InnerStruct'}, 'InterestPayments': ('None',), 'PayDownSchedule': ('None',), 'Internal': {'ValuationMethod': 'scale_info::122', 'ProbabilityOfDefault': 'u128', 'LossGivenDefault': 'u128', 'DiscountRate': 'scale_info::117'}}), 'Policy': [{'triggers': 'scale_info::129', 'status': 'scale_info::131'}], 'TransferDebt': ('u64', 'u64', {'principal': {'Internal': 'u128', 'External': 'scale_info::135'}, 'interest': 'u128', 'unscheduled': 'u128'}, {'Internal': 'u128', 'External': {'quantity': 'u128', 'settlement_price': 'u128'}})}, 'OracleCollection': {'CollectionInfo': {'value_lifetime': (None, 'u64'), 'min_feeders': 'u32', 'feeders': 'scale_info::162'}}, 'PoolFee': {'AppendFee': ('u64', ('Top',), {'destination': 'AccountId', 'editor': {'Root': None, 'Account': 'AccountId'}, 'fee_type': {'Fixed': 'InnerStruct', 'ChargedUpTo': 'InnerStruct'}})}, '_Unreachable': None}

Rebalanced

The tranches were rebalanced.

Attributes

Name Type Composition
pool_id T::PoolId u64

SolutionSubmitted

An epoch was executed.

Attributes

Name Type Composition
pool_id T::PoolId u64
epoch_id T::EpochId u32
solution EpochSolution<T::Balance, T::MaxTranches> {'Healthy': {'solution': [{'invest_fulfillment': 'u64', 'redeem_fulfillment': 'u64'}], 'score': 'u128'}, 'Unhealthy': {'state': [('MaxReserveViolated', 'MinRiskBufferViolated')], 'solution': [{'invest_fulfillment': 'u64', 'redeem_fulfillment': 'u64'}], 'risk_buffer_improvement_scores': (None, ['u128']), 'reserve_improvement_score': (None, 'u128')}}

Updated

A pool was updated.

Attributes

Name Type Composition
id T::PoolId u64
old PoolEssenceOf<T> {'currency': {'Native': None, 'Tranche': ('u64', '[u8; 16]'), None: None, 'AUSD': None, 'ForeignAsset': 'u32', 'Staking': ('BlockRewards',), 'LocalAsset': 'u32'}, 'max_reserve': 'u128', 'max_nav_age': 'u64', 'min_epoch_time': 'u64', 'tranches': [{'currency': {'pool_id': 'u64', 'tranche_id': '[u8; 16]'}, 'ty': {'Residual': None, 'NonResidual': {'interest_rate_per_sec': 'u128', 'min_risk_buffer': 'u64'}}, 'metadata': {'token_name': 'Bytes', 'token_symbol': 'Bytes'}}]}
new PoolEssenceOf<T> {'currency': {'Native': None, 'Tranche': ('u64', '[u8; 16]'), None: None, 'AUSD': None, 'ForeignAsset': 'u32', 'Staking': ('BlockRewards',), 'LocalAsset': 'u32'}, 'max_reserve': 'u128', 'max_nav_age': 'u64', 'min_epoch_time': 'u64', 'tranches': [{'currency': {'pool_id': 'u64', 'tranche_id': '[u8; 16]'}, 'ty': {'Residual': None, 'NonResidual': {'interest_rate_per_sec': 'u128', 'min_risk_buffer': 'u64'}}, 'metadata': {'token_name': 'Bytes', 'token_symbol': 'Bytes'}}]}

Storage functions


AccountDeposit

Python

result = substrate.query(
    'PoolSystem', 'AccountDeposit', ['AccountId']
)

Return value

'u128'

EpochExecution

Python

result = substrate.query(
    'PoolSystem', 'EpochExecution', ['u64']
)

Return value

{
    'best_submission': (
        None,
        {
            'Healthy': {'score': 'u128', 'solution': ['scale_info::90']},
            'Unhealthy': {
                'reserve_improvement_score': (None, 'u128'),
                'risk_buffer_improvement_scores': (None, ['u128']),
                'solution': ['scale_info::90'],
                'state': ['scale_info::95'],
            },
        },
    ),
    'challenge_period_end': (None, 'u32'),
    'epoch': 'u32',
    'nav': {'nav_aum': 'u128', 'nav_fees': 'u128'},
    'tranches': {
        'tranches': [
            {
                'currency': 'scale_info::102',
                'invest': 'u128',
                'min_risk_buffer': 'u64',
                'price': 'u128',
                'redeem': 'u128',
                'seniority': 'u32',
                'supply': 'u128',
            },
        ],
    },
}

NotedChange

Python

result = substrate.query(
    'PoolSystem', 'NotedChange', ['u64', 'scale_info::12']
)

Return value

{
    'change': {
        'Loans': {
            'Loan': (
                'u64',
                {
                    'InterestPayments': 'scale_info::119',
                    'InterestRate': 'scale_info::117',
                    'Internal': 'scale_info::121',
                    'Maturity': 'scale_info::116',
                    'MaturityExtension': 'u64',
                    'PayDownSchedule': 'scale_info::120',
                },
            ),
            'Policy': ['scale_info::125'],
            'TransferDebt': (
                'u64',
                'u64',
                {
                    'interest': 'u128',
                    'principal': 'scale_info::134',
                    'unscheduled': 'u128',
                },
                {'External': 'scale_info::135', 'Internal': 'u128'},
            ),
        },
        'OracleCollection': {
            'CollectionInfo': {
                'feeders': 'scale_info::162',
                'min_feeders': 'u32',
                'value_lifetime': (None, 'u64'),
            },
        },
        'PoolFee': {
            'AppendFee': (
                'u64',
                ('Top', ),
                {
                    'destination': 'AccountId',
                    'editor': 'scale_info::167',
                    'fee_type': 'scale_info::168',
                },
            ),
        },
        '_Unreachable': None,
    },
    'submitted_time': 'u64',
}

Pool

Python

result = substrate.query(
    'PoolSystem', 'Pool', ['u64']
)

Return value

{
    'currency': {
        'Native': None,
        'Tranche': ('u64', '[u8; 16]'),
        None: None,
        'AUSD': None,
        'ForeignAsset': 'u32',
        'LocalAsset': 'u32',
        'Staking': ('BlockRewards', ),
    },
    'epoch': {'current': 'u32', 'last_closed': 'u64', 'last_executed': 'u32'},
    'parameters': {'max_nav_age': 'u64', 'min_epoch_time': 'u64'},
    'reserve': {'available': 'u128', 'max': 'u128', 'total': 'u128'},
    'status': ('Open', ),
    'tranches': {
        'ids': ['[u8; 16]'],
        'salt': ('u64', 'u64'),
        'tranches': [
            {
                'currency': 'scale_info::102',
                'debt': 'u128',
                'last_updated_interest': 'u64',
                'loss': 'u128',
                'ratio': 'u64',
                'reserve': 'u128',
                'seniority': 'u32',
                'tranche_type': 'scale_info::108',
            },
        ],
    },
}

PoolDeposit

Python

result = substrate.query(
    'PoolSystem', 'PoolDeposit', ['u64']
)

Return value

{'deposit': 'u128', 'depositor': 'AccountId'}

ScheduledUpdate

Python

result = substrate.query(
    'PoolSystem', 'ScheduledUpdate', ['u64']
)

Return value

{
    'changes': {
        'max_nav_age': {'NewValue': 'u64', 'NoChange': None},
        'min_epoch_time': {'NewValue': 'u64', 'NoChange': None},
        'tranche_metadata': {'NewValue': ['scale_info::109'], 'NoChange': None},
        'tranches': {'NewValue': ['scale_info::374'], 'NoChange': None},
    },
    'submitted_at': 'u64',
}

Constants


ChallengeTime

Challenge time

Value

150

Python

constant = substrate.get_constant('PoolSystem', 'ChallengeTime')

DefaultMaxNAVAge

Value

0

Python

constant = substrate.get_constant('PoolSystem', 'DefaultMaxNAVAge')

DefaultMinEpochTime

Pool parameter defaults

Value

85800

Python

constant = substrate.get_constant('PoolSystem', 'DefaultMinEpochTime')

MaxNAVAgeUpperBound

Value

0

Python

constant = substrate.get_constant('PoolSystem', 'MaxNAVAgeUpperBound')

MaxTokenNameLength

Max length for a tranche token name

Value

128

Python

constant = substrate.get_constant('PoolSystem', 'MaxTokenNameLength')

MaxTokenSymbolLength

Max length for a tranche token symbol

Value

32

Python

constant = substrate.get_constant('PoolSystem', 'MaxTokenSymbolLength')

MaxTranches

Max number of Tranches

Value

5

Python

constant = substrate.get_constant('PoolSystem', 'MaxTranches')

MinEpochTimeLowerBound

Pool parameter bounds

Value

3600

Python

constant = substrate.get_constant('PoolSystem', 'MinEpochTimeLowerBound')

MinEpochTimeUpperBound

Value

2592000

Python

constant = substrate.get_constant('PoolSystem', 'MinEpochTimeUpperBound')

MinUpdateDelay

Pool update settings

Value

172800

Python

constant = substrate.get_constant('PoolSystem', 'MinUpdateDelay')

PalletId

Value

'0x726f632f706f6f6c'

Python

constant = substrate.get_constant('PoolSystem', 'PalletId')

PalletIndex

The immutable index of this pallet when instantiated within the context of a runtime where it is used.

Value

99

Python

constant = substrate.get_constant('PoolSystem', 'PalletIndex')

PoolDeposit

The amount that must be reserved to create a pool

Value

0

Python

constant = substrate.get_constant('PoolSystem', 'PoolDeposit')

Errors


CannotAddOrRemoveTranches

Adding & removing tranches is not supported


ChallengeTimeHasNotPassed

Attempted to execute an epoch too early


ChangeNotFound

The external change was not found for the specified ChangeId.


ChangeNotReady

The external change was found for is not ready yet to be released.


EpochNotExecutedYet

Epoch needs to be executed before you can collect


FailedToRegisterTrancheMetadata

Registering the metadata for a tranche threw an error


FailedToUpdateTrancheMetadata

Updating the metadata for a tranche threw an error


InSubmissionPeriod

Cannot be called while the pool is in a submission period


InsufficientCurrency

Insufficient currency available for desired operation


InvalidCurrency

A user has tried to create a pool with an invalid currency


InvalidJuniorTranche

Attempted to create a pool without a junior tranche


InvalidSolution

The provided solution is not a valid one


InvalidTrancheId

Invalid TrancheId passed. In most cases out-of-bound index


InvalidTrancheSeniority

Invalid tranche seniority value * seniority MUST be smaller number of tranches * MUST be increasing per tranche


InvalidTrancheStructure

Attempted to create a tranche structure where * non-decreasing interest rate per tranche


InvalidTrancheUpdate

Pre-requirements for a TrancheUpdate are not met for example: Tranche changed but not its metadata or vice versa


MetadataForCurrencyNotFound

No metada for the given currency found


MinEpochTimeHasNotPassed

Attempted to close an epoch too early


Attempted to close an epoch with an out of date NAV


NoNAV

The NAV was not available


NoScheduledUpdate

No update for the pool is scheduled


NoSolutionAvailable

No solution has yet been provided for the epoch


NoSuchPool

Attempted an operation on a pool which does not exist


NotInSubmissionPeriod

Attempted to solve a pool which is not in a submission period


NotNewBestSubmission

Submitted solution is not an improvement


PoolInUse

A pool with this ID is already in use


PoolParameterBoundViolated

One of the runtime-level pool parameter bounds was violated


RiskBufferViolated

Risk Buffer validation failed


ScheduledTimeHasNotPassed

Scheduled time for this update is in the future


TooManyTranches

The requested tranche configuration has too many tranches


TrancheId

A Tranche ID cannot be converted to an address


TrancheSymbolNameTooLong

The given tranche symbol name exceeds the length limit


TrancheTokenNameTooLong

The given tranche token name exceeds the length limit


UpdatePrerequesitesNotFulfilled

Update cannot be fulfilled yet


WipedOut

Closing the epoch now would wipe out the junior tranche