ELIP: 202 Layer: Applications Title: Optional sidechain peg-in subsidy and minimum peg-in amount Author: Byron Hambly <bhambly@blockstream.com> Comments-Summary: No comments yet. Comments-URI: https://github.com/ElementsProject/elips/wiki/Comments:ELIP-0202 Status: Draft Type: Standards Track Created: 2025-09-01 License: BSD-3-Clause
This document proposes an optional mempool policy and configuration for Elements sidechains to require that users pay a subsidy for peg-in transactions, and/or to enforce a minimum peg-in amount.
The subsidy is a required OP_RETURN output on sidechain peg-in claim transactions, that burns an amount proportional to the fee rate of the parent transaction. This subsidizes the cost of spending these outputs for the sidechain operator at similar fee rates.
This document is licensed under the 3-clause BSD license.
Sidechain operators manage the funds on the parent chain, where each peg-in transaction creates a new output in their control. Depending on their wallet setup, they may face large fees when consolidating or renewing timelocks on these outputs.
The optional mempool policies proposed here give sidechain operators configurable options to enable a peg-in subsidy from a specific chain height, an amount threshold above which no subsidy is required, and a minimum peg-in amount from a specified height.
These options allow the operator to ensure that new outputs from peg-ins subsidize the cost of their own consolidation, and encourage users to use alternative options like atomic swaps for amounts below the subsidy threshold.
New optional configurable chain parameters are added to Elements: peg-in subsidy height, peg-in subsidy threshold amount, peg-in minimum height, and peg-in minimum amount. Their default values leave them disabled unless specified. If a subsidy height is set, then from that height a peg-in transaction must include a subsidy output if the value of the peg-in is below the subsidy threshold value. Independently, if a minimum peg-in amount is set then any peg-in value must be greater than that minimum amount, after the peg-in minimum block height.
A subsidy output is an OP_RETURN output in the sidechain claim transaction that burns a value equal to spending the new parent output at the parent transaction fee rate. Elements RPCs claimpegin and createrawpegin are modified to create these subsidy outputs when required, and mempool policy validation is added to check for subsidies and minimum peg-in amounts as configured.
New options are added to Elements configuration: peginsubsidyheight, peginsubsidythreshold, peginminheight, and peginminamount. By default, these are unset. For peginsubsidythreshold and peginminamount this is an amount of 0, and for peginsubsidyheight and peginminheight this is the value of int32 max.
New mempool validation is implemented to check for a peg-in subsidy from the subsidy height. This requires that a peg-in transaction, whose value is below the subsidy threshold, must contain one or more OP_RETURN outputs burning the value of spending a P2WSH output on the parent chain at the same fee rate as the parent peg-in. If the parent fee rate is below 1 sat/vb, the peg-in subsidy must be calculated as if the parent transaction fee rate was 1 sat/vb. A new policy will also reject peg-ins below the minimum peg-in amount after the minimum peg-in height.
This validation requires that the sidechain node is validating peg-ins against the parent node, as the sidechain node calls getrawtransaction to retrieve the fee paid and vsize of the parent transaction to calculate its fee rate. If the sidechain node is not validating peg-ins (validatepegin=0), it cannot calculate the parent fee rate. The RPCs for claimpegin and createrawpegin are updated with a new optional parameter to specify the parent fee rate manually. For mempool validation, a sidechain node with validatepegin=0 will check for the minimum 1 sat/vb parent fee rate subsidy calculation to determine if it should be relayed, but if the parent fee rate was greater than 1 sat/vb, it will not be relayed by nodes that are validating peg-ins.
It is expected that the Federated Peg script (fedpegscript) starts with a t-of-n OP_CHECKMULTISIG path, followed by optional fallback spending conditions.
The value of the required subsidy for peg-ins below the threshold after the subsidy chain height is calculated as follows:
- count the number of the peg-in inputs in the transaction
- decompose the peg-in input witness into its constituent parts: amount, asset, genesis hash, claim script, parent transaction, and Merkle block
- calculate the parent txid from the parent transaction, and the parent block hash from the header of the Merkle block
- call
getrawtransactionon the parent node with the txid, block hash, and verbose=2 to return the parent transaction and fee information - use the returned fee and vsize to calculate the fee rate of the parent transaction(s) in sats/vb. If this is below 1 sat/vb, use the value 1 sat/vb as the parent fee rate.
- from the fedpegscript parse the value for
tof the firstOP_CHECKMULTISIGscript - multiply the parent fee rate by the number of peg-in inputs and the cost of spending a P2WSH output with
tsignatures
- Weight of non-witness data:
prev txid (32 bytes) + vout (4 bytes) + scriptsig len (1 byte) + sequence number (4 bytes) = 41 * WITNESS_SCALE_FACTOR (4) = 164 WU - Weight of witness data:
t * signatures (72 bytes) + size of fedpegscript (variable) = WITNESS_BYTES WU - Virtual size for spending this input:
(164 + WITNESS_BYTES + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR = VSIZE vbytes
OP_RETURN) output for the peg-in whose value is below the threshold is then:
fee rate of parent transaction in sat/vbyte (at a min of 1 sat/vb) * VSIZE vbytes
t-of-n quorum is 11-of-15, and with fallback script the total size is 626 bytes.
This gives the following calculation for the peg-in subsidy on Liquidv1, if/when it is active and the value is below the subsidy threshold:
WITNESS_BYTES = 11 * 72 + 626 = 1418 WUVSIZE = (164 + 1418 + 3) / 4 = 396 vbytes
To generalize this for Liquidv1 peg-in claims: required subsidy = max(parent fee rate, 1 sat/vb) * number of peg-ins * 396 Lsat, where total parent fee rate = sum of parent fees / sum of parent vsizes.
Wallets implementing peg-in claim transactions after the subsidy height, for values below the subsidy threshold, must subtract the subsidy value from the peg-in value, and add an OP_RETURN output with that value. The value must be calculated as given above, which for a Liquidv1 peg-in claim for a single peg-in output at 1 sat/vb parent fee rate is 396 Lsat.
The Elements wallet RPCs claimpegin and createrawpegin can do this automatically when validatepegin=1, or manually only by specifying the parent fee rate when validatepegin=0.
The Elements RPCs for getpeginaddress and getsidechaininfo are updated to return relevant details about the peg-in subsidy height and threshold, and peg-in minimum height and amount in their responses, if configured.
These changes are in mempool policy validation only and have no effect on consensus. Un-upgraded nodes will not create the required subsidy outputs, but upgraded block creators will not accept these transactions after the subsidy height enforcement.
todo
For a t-of-n fedpegscript of size S bytes with configuration peginsubsidyheight=H and peginsubsidythreshold=X:
Before block height H:
- no subsidy is required for any peg-in value
H:
- no subsidy is required for a total peg-in value of
XBTC or greater
P peg-in outputs with total value below X BTC:
- at a parent fee rate of
F[1] sat/vb, the claim transaction requires a subsidy of:F * P * (164 + t * 72 + S + 3) / 4sidechain satoshis
For an 11-of-15 fedpegscript of size 626 bytes (Liquidv1) with configuration peginsubsidyheight=5000 and peginsubsidythreshold=1.0:
Before block height 5000:
- no subsidy is required for any peg-in value
5000:
- no subsidy is required for a total peg-in value
1.0BTC or greater
P peg-in outputs with total value below 1.0 BTC:
- at a parent fee rate of
Fsat/vb, the claim transaction requires a subsidy of:F * P * (164 + 11 * 72 + 626 + 3) / 4Lsat
1.0 BTC:
- at a parent fee rate of 0.1 sat/vb, the claim transaction requires a subsidy of 396 Lsat
- at a parent fee rate of 1 sat/vb, the claim transaction requires a subsidy of 396 Lsat
- at a parent fee rate of 2 sat/vb, the claim transaction requires a subsidy of 792 Lsat
- at a parent fee rate of 3 sat/vb, the claim transaction requires a subsidy of 1188 Lsat
- at a parent fee rate of 4 sat/vb, the claim transaction requires a subsidy of 1584 Lsat
- at a parent fee rate of 10 sat/vb, the claim transaction requires a subsidy of 3960 Lsat
- at a parent fee rate of 0.1 sat/vb, the claim transaction requires a subsidy of 792 Lsat
- at a parent fee rate of 1 sat/vb, the claim transaction requires a subsidy of 792 Lsat
- at a parent fee rate of 2 sat/vb, the claim transaction requires a subsidy of 1584 Lsat
- at a parent fee rate of 3 sat/vb, the claim transaction requires a subsidy of 2376 Lsat
- at a parent fee rate of 4 sat/vb, the claim transaction requires a subsidy of 3168 Lsat
- at a parent fee rate of 10 sat/vb, the claim transaction requires a subsidy of 7920 Lsat
- ^ F = max(parent fee rate, 1 sat/vb)