Skip to content

Commit 9408824

Browse files
authored
Merge commit from fork
* fix: reject close voucher equal to on-chain settled amount * chore: version 0.4.11 * Revert "chore: version 0.4.11" This reverts commit 8465ddeecc738aeef689b2d772096647c39ec0aa.
1 parent 7055bd1 commit 9408824

File tree

3 files changed

+41
-3
lines changed

3 files changed

+41
-3
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'mppx': patch
3+
---
4+
5+
Fixed close voucher validation to reject vouchers equal to the on-chain settled amount.

src/tempo/server/Session.test.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,6 +1143,35 @@ describe.runIf(isLocalnet)('session', () => {
11431143
).rejects.toThrow('close voucher amount must be >=')
11441144
})
11451145

1146+
test('rejects close equal to on-chain settled amount', async () => {
1147+
const { channelId, serializedTransaction } = await createSignedOpenTransaction(10000000n)
1148+
const server = createServer()
1149+
1150+
// Open with 1M voucher (matches openServerChannel default)
1151+
await openServerChannel(server, channelId, serializedTransaction)
1152+
1153+
// Settle on-chain so settled becomes 1000000
1154+
const settleTxHash = await settle(store, client, channelId, { escrowContract })
1155+
await waitForTransactionReceipt(client, { hash: settleTxHash })
1156+
1157+
// Try to close with voucher == on-chain settled — should be rejected
1158+
// because replaying the settled amount doesn't commit new funds
1159+
await expect(
1160+
server.verify({
1161+
credential: {
1162+
challenge: makeChallenge({ id: 'challenge-2', channelId }),
1163+
payload: {
1164+
action: 'close' as const,
1165+
channelId,
1166+
cumulativeAmount: '1000000',
1167+
signature: await signTestVoucher(channelId, 1000000n),
1168+
},
1169+
},
1170+
request: makeRequest(),
1171+
}),
1172+
).rejects.toThrow('close voucher amount must be >')
1173+
})
1174+
11461175
test('rejects close exceeding on-chain deposit', async () => {
11471176
const { channelId, serializedTransaction } = await createSignedOpenTransaction(10000000n)
11481177
const server = createServer()

src/tempo/server/Session.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -815,10 +815,14 @@ async function handleClose(
815815
throw new ChannelClosedError({ reason: 'channel is finalized on-chain' })
816816
}
817817

818-
const minCloseAmount = channel.spent > onChain.settled ? channel.spent : onChain.settled
819-
if (voucher.cumulativeAmount < minCloseAmount) {
818+
if (voucher.cumulativeAmount < channel.spent) {
820819
throw new VerificationFailedError({
821-
reason: `close voucher amount must be >= ${minCloseAmount} (max of spent and on-chain settled)`,
820+
reason: `close voucher amount must be >= ${channel.spent} (spent)`,
821+
})
822+
}
823+
if (voucher.cumulativeAmount <= onChain.settled) {
824+
throw new VerificationFailedError({
825+
reason: `close voucher amount must be > ${onChain.settled} (on-chain settled)`,
822826
})
823827
}
824828

0 commit comments

Comments
 (0)