# 27 - Dash Core Credit Pool
DIP: 0027
Title: Dash Core Credit Pool
Chain: Core
Author(s): Ivan Shumkov, Anton Suprunchuk, Thephez, Samuel Westrich
Special-Thanks: Konstantin Akimov, Virgile Bartolo, Odysseas Gabrielides, UdjinM6
Comments-Summary: No comments yet.
Status: Proposed
Type: Standard
Created: 2024-05-08
License: MIT License
# Table of Contents
* [Abstract](#abstract)
* [Motivation](#motivation)
* [Previous Work](#previous-work)
* [System Requirements](#system-requirements)
* [Overview](#overview)
* [Asset Locking](#asset-locking)
* [Asset Lock Transaction](#asset-lock-transaction)
* [Proof of Finality](#proof-of-finality)
* [Asset Unlocking](#asset-unlocking)
* [Asset Unlock Transaction](#asset-unlock-transaction)
* [Client verification](#client-verification)
* [Withdrawal Completion](#withdrawal-completion)
* [Withdrawal Safety](#withdrawal-safety)
* [Updated Coinbase Transaction](#updated-coinbase-transaction)
* [Copyright](#copyright)
## Abstract
This DIP provides a mechanism for locking and unlocking Dash in a new store of value on the Core chain. The store of value, called the credit pool, mirrors the credit balance on Dash Platform. New special transactions enable locking Dash in the credit pool for use on Platform and unlocking it to withdraw back to Dash on the Core chain.
## Motivation
Dash Platform is a Scalable Byzantine Fault Tolerant based consensus network offering novel features not currently possible on the Dash Core blockchain. It uses a medium of exchange called credits to support its fee system and distribute Platform rewards to Evolution masternodes. Credits are based on the Dash Core chain, as explained in [DIP-11](./dip-0011.md), and bi-directional conversion between Dash and credits is supported.
The challenge in supporting the conversion arises due to credit withdrawals. If low-value transactions locked Dash to create credits, a UTXO-based solution could require multiple small inputs to unlock the requested withdrawal amount. Since each input increases the transaction size, the transaction fee would be higher. Consequently, the person requesting the withdrawal might be stuck with a large transaction fee due to the small amounts others locked when creating credits.
Switching to the credit pool relieves this issue by allowing withdrawals to be paid out as a zero-input transaction (similar to coinbase transactions). The credit pool tracks the total balance of locked funds and allows spending from that balance instead of having to assemble individual UTXOs that add up to the withdrawal amount. This design ensures that fees for unlocking Dash remain predictable and that even low-value locking transactions can be unlocked.
## Previous Work
* [DIP-0002: Special transactions](https://github.com/dashpay/dips/blob/master/dip-0002.md)
* [DIP-0004: Simplified Verification of Deterministic Masternode Lists](https://github.com/dashpay/dips/blob/master/dip-0004.md)
* [DIP-0007: LLMQ Signing Requests / Sessions](https://github.com/dashpay/dips/blob/master/dip-0007.md)
* [DIP-0010: LLMQ InstantSend](https://github.com/dashpay/dips/blob/master/dip-0010.md)
* [DIP-0011: Identities](https://github.com/dashpay/dips/blob/master/dip-0011.md)
## System Requirements
Two criteria must be met for the credit pool to operate effectively:
1. The value of Dash in the credit pool must always correspond to the number of credits on Platform. The Core blockchain does this by tracking the amount of locked Dash and preventing Dash above that amount from being withdrawn.
2. Withdrawing Dash from credits must be possible without requiring the Core chain to validate any Platform constructs, such as Identities. This minimizes the level of reliance between Core and Platform.
## Overview
When Dash is locked in the credit pool, the person who locked it can claim a corresponding number of credits for an Identity on Dash Platform. As the Identity performs actions on Platform, its balance is reduced by the cost of the actions while the masternode payout pool value is increased by the same amount. Over time, funds in the masternode payout pool are distributed to the Identities of masternodes that participated in Platform validator sets. The details of masternode Identities and Platform payouts will be the focus of future DIPs.
Eventually, an Identity may want to withdraw their credits from Platform to regain access to the underlying locked Dash. Any Identity type can issue a withdrawal request to Dash Platform. If the Identity’s balance is sufficient, this will result in the formation of a transaction signed by a quorum and valid on the Core chain. This transaction unlocks the requested amount of Dash from the credit pool and sends it to the provided Dash address.
## Asset Locking
Dash Core participates in the credit creation process by locking Dash in the credit pool with an Asset Lock transaction.
### Asset Lock Transaction
The Asset Lock transaction (AssetLockTx) is a DIP-2-based special transaction that gives Platform the information required to assign credits to Identities. This special transaction is type 8.
The format of the Asset Lock special transaction payload:
| **Name** | **Type** | **Size** | **Description** |
| - | - | - | - |
| version | uint8_t | 1 | Asset Lock transaction version number |
| count | uint8_t | 1 | The number of accounts funded via this Asset Lock |
| credit_outputs | vec\ | 28 * count| The hash of the public key(s) used to claim credits on Dash Platform, as well as the amount of Dash in duffs transferred into credits for this public key hash |
Each Asset Lock transaction must create an unspendable output by using an OP_RETURN as the first script. An Asset Lock transaction may only include a single OP_RETURN output. Additionally, the following criteria apply to the OP_RETURN output:
* It must not include any data
* Its value is the amount of Dash to be locked
* The sum of all TxOut amounts must equal the value of the output
### Proof of Finality
It is important to note that Dash Core transactions achieve finality through ChainLocks and InstantSend locks. Therefore, these locks can be used to prove that value has been added to the credit pool and is ready for Platform use. For example, Platform can safely increase an Identity’s balance without concerns that the related Asset Lock transaction will be double-spent.
There are two ways to prove transaction finality: either by including the InstantSend lock of a recent transaction or by referencing the chain height at which a transaction was included in a ChainLocked block or any higher ChainLock. Typically, it is preferable to use the InstantSend lock for proof, but a ChainLock can be used if an InstantSend lock is not available.
## Asset Unlocking
Withdrawing locked credit pool funds back to Dash is done by creating a Core chain unlock transaction signed by a Platform validator quorum (e.g., LLMQ_100_67 for mainnet). This transaction will release Dash from the credit pool while reducing the credit pool balance by an equivalent amount.
### Asset Unlock Transaction
The Asset Unlock transaction (AssetUnlockTx) is a DIP-2-based special transaction that enables the withdrawal of credit pool funds as Dash. This special transaction is type 9.
Note: Asset Unlock transactions have no inputs. Their uniqueness is instead derived from the index they contain, which must be unique.
The format of the Asset Unlock special transaction payload:
| **Field** | **Type** | **Size** | **Description** |
| - | - | - | - |
| version | uint8_t | 1 | Asset Unlock version number. Currently set to 1 |
| index | uint64 | 8 | The index of the transaction |
| fee | uint32 | 4 | The miner's fee in duffs |
| signHeight | uint32 | 4 | The height of the Core chain known by Platform at the moment of the Asset Unlock signing (Core ChainLock height) |
| quorumHash | uint256 | 32 | Quorum hash. Set by the current validator. Must refer to an active quorum at `signHeight` |
| quorumSig | uint768 | 96 | Threshold signature recovered during Platform Consensus. Must be a signature for the full transaction, not just the payload. |
#### Signing Asset Unlock Transactions
An active Platform validator quorum quorum must sign Asset Unlock transactions per the process described in [DIP-7](./dip-0007.md). The signing session parameters are:
| DIP-7 parameter | Value |
|-|-|
| Request ID | `SHA256(SHA256("plwdtx", index))` |
| Message hash | The asset lock transaction, with the `quorumSig` field set to zeros, hashed as described in [DIP-2](./dip-0002.md#serialization-hashing-and-signing) |
For reference, the following table shows some example index values and their request IDs. See the [provided script](dip-0027/dip-0027-request-id-calc.py) for example code:
| **Index** | **Request ID** |
|-----------|----------------|
| 101 | fcc76a643c5c668244fdcef09833955d6f4b803fa6c459f7732983c2332389fd |
| 123456789 | ebd9d75ad72184bec8e8f25a499eb5386ba564eb7ce70a4a3b9db652599d6d72 |
### Client verification
All clients must verify the quorumSig field before accepting the transaction. Quorum signatures must be created by a recent quorum (one that is currently active or the most recently replaced one) to be considered valid. If the quorum is recent and the transaction is not yet mined, light clients should attempt to verify the quorumSig by retrieving the quorum public key as described in DIP-4 and verifying the signature. If the quorum is not recent and the transaction is not mined, the transaction should be ignored until it is mined to prevent attacks on the light client.
### Withdrawal Completion
Since Asset Unlock transactions do not have inputs, they are not eligible for InstantSend. Once mined into a block and subsequently ChainLocked, they are final and identical to all other outputs. A withdrawal should be considered complete when the corresponding Asset Unlock transaction is finalized on the Core chain.
Asset Unlock transactions might not be mined for multiple reasons. For example, the quorum who signed a transaction expired, Core fees were too low, or the withdrawal limit was reached. To handle this situation, Asset Unlock transactions have an expiration period based on the quorum lifetime. Transactions are considered invalid if not signed by one of the active quorums or the most recently replaced quorum. In this case, the issuer can retry the withdrawal. To ensure that expired transactions are not included in the Core chain, Asset Lock transactions are refused once the block height exceeds _signHeight_ by 48 or more (i.e., height > _signHeight_ + 48).
## Withdrawal Safety
As a way to avoid a catastrophic failure if Platform is compromised, Core will limit credit pool withdrawals for at least the first release of Platform. The withdrawal limits may be re-evaluated and updated periodically as the system matures. To evaluate withdrawal validity, withdrawal amounts from the last 576 blocks should be tallied. The withdrawal should not be mined if:
* It requests more DASH than the credit pool contains
* The withdrawal would result in more than a 2000 DASH reduction in the credit pool over the past 576 blocks
Prior to activation of the `withdrawals` hard fork in Dash Core v22.0, more restrictive limits were followed. The withdrawal would not be mined if:
* The withdrawal would result in more than a 1000 DASH reduction in the credit pool over the past 576 blocks
* The credit pool contains more than 1000 DASH, and the withdrawal would result in more than a 10% reduction in the credit pool over the 576-block window
* The credit pool contains less than 1000 DASH, and the withdrawal would result in more than 100 DASH being removed from the pool over the 576-block window
## Updated Coinbase Transaction
As described [in the latest version of DIP-4](./dip-0004.md#coinbase-special-transaction), coinbase transaction versions >= 3 include the creditPoolBalance field:
| **Field** | **Type** | **Size** | **Description** |
| -| - | - | - |
| creditPoolBalance | int64_t | 8 | The total amount of duffs locked at the block height |
The creditPoolBalance field represents the total amount of Dash (in duffs) locked at the block height. The value of this field must be equal to the value of this field in the previous block PLUS the sum of all Dash locked by Asset Lock transactions included in the block MINUS the sum of all Dash unlocked by Asset Unlock transactions in the block. So, for height x, the creditPoolBalance is:
creditPoolBalance = creditPoolBalance(x-1) + AssetLockTxs(x) - AssetUnlockTxs(x)
## Copyright
Copyright (c) 2024 Dash Core Group, Inc. [Licensed under the MIT License](https://opensource.org/licenses/MIT)