Skip to content

Account for the mainchain fee in withdrawal value to keep the peg solvent#86

Open
1440000bytes wants to merge 2 commits into
LayerTwo-Labs:masterfrom
1440000bytes:fix-withdrawal-main-fee-accounting
Open

Account for the mainchain fee in withdrawal value to keep the peg solvent#86
1440000bytes wants to merge 2 commits into
LayerTwo-Labs:masterfrom
1440000bytes:fix-withdrawal-main-fee-accounting

Conversation

@1440000bytes

Copy link
Copy Markdown

get_value for a withdrawal output returned only value, ignoring main_fee. But the enforcer pays both out of the treasury when it builds the M6: BlindedM6::into_m6 sets treasury_out = treasury - payout - fee, where payout is the sum of the bundle payout amounts (value) and fee is the bundle's encoded mainchain fee (main_fee).

So each withdrawal removed value + main_fee from the treasury while the sidechain destroyed only value. Every withdrawal eroded the peg's backing by main_fee and since nothing bounds main_fee, an attacker could withdraw a tiny value with a large main_fee and drain the treasury at near-zero sidechain cost, eventually making the peg insolvent (late withdrawals hit the checked_sub underflow and fail).

The wallet reinforced this: create_withdrawal selected coins for value + fee + main_fee but computed change = total - value - fee, refunding main_fee back to the withdrawer.

Fix

  • get_value for a withdrawal returns value + main_fee, so the sidechain destroys exactly what leaves the treasury. Uses checked_add saturating at Amount::MAX to avoid a panic on a crafted overflowing output (such an output can never be funded, so it is rejected rather than crashing).
  • create_withdrawal subtracts main_fee from the change as well, so wallet built withdrawals stay valid under the corrected accounting.

Test

Added a unit test asserting a withdrawal output's value is value + main_fee, that inputs covering only value fail fee computation, and that inputs covering value + main_fee leave exactly zero fee. It fails on the old code and passes with the fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant