Skip to content

fix: security hardening - CEI pattern, over-withdrawal guard, debt settlement#13

Open
giwaov wants to merge 1 commit intocirclefin:masterfrom
giwaov:fix/security-hardening
Open

fix: security hardening - CEI pattern, over-withdrawal guard, debt settlement#13
giwaov wants to merge 1 commit intocirclefin:masterfrom
giwaov:fix/security-hardening

Conversation

@giwaov
Copy link
Copy Markdown

@giwaov giwaov commented Apr 7, 2026

Summary

This PR addresses three security vulnerabilities in RefundProtocol.sol:

1. Reentrancy risk in _executeRefund (fixes #12)

The _executeRefund\ function performed an external \ iatToken.transfer()\ call before updating \payments[paymentID].refunded = true. This violates the checks-effects-interactions (CEI) pattern and opens a reentrancy vector if the token contract is malicious or upgradeable.

Fix: Move the state update (\payments[paymentID].refunded = true) before the external transfer call.

2. Over-withdrawal via repeated earlyWithdrawByArbiter calls (fixes #11)

The \earlyWithdrawByArbiter\ function checks \withdrawalAmount > payment.amount\ per payment but never validates the cumulative withdrawn amount. An arbiter could call this function multiple times to withdraw more than the payment amount.

Fix: Add a cumulative check: \payment.withdrawnAmount + withdrawalAmount > payment.amount.

3. Debt bypass in refundByRecipient (fixes #10)

The
efundByRecipient\ function does not call _settleDebt(msg.sender)\ before checking and deducting the recipient's balance, unlike \withdraw()\ which does settle debt first. This means a recipient with outstanding debt can get a full refund without settling.

Fix: Add _settleDebt(msg.sender)\ call before the balance check, matching the pattern in \withdraw().

Testing

All 36 existing tests pass:

\
forge test -vv

36 passed, 0 failed, 0 skipped

\\

Changes

  • \src/RefundProtocol.sol: +7/-1 lines across three targeted fixes

…ttlement

- Fix reentrancy risk in _executeRefund by setting refunded=true before
  external transfer call (checks-effects-interactions pattern) (circlefin#12)
- Add cumulative withdrawal check in earlyWithdrawByArbiter to prevent
  over-withdrawal via repeated calls (circlefin#11)
- Add _settleDebt call in refundByRecipient to prevent debt bypass (circlefin#10)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant