feat(guards): implement flash-loan reentrancy guard using block number verification - #821
Open
rabsqueen wants to merge 1 commit into
Open
Conversation
|
@rabsqueen Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
Contributor
|
@rabsqueen there's no CI check here |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
[SECURITY] Add Flash-Loan Reentrancy Guard
Summary
Implements a transaction-level reentrancy guard for the Yield-Bearing Fee Vault to prevent a user from depositing and withdrawing within the same transaction.
The protection combines a simple non-reentrant lock with deposit ledger tracking. Each deposit records the current ledger/block number, and withdrawals are only permitted from a subsequent ledger.
This prevents flash-loan-style deposit → withdraw sequences from bypassing the vault's intended settlement timing.
What Changed
🔒 Non-Reentrant Lock
Added a lightweight contract-level lock around the protected vault operations.
The guard ensures that a protected operation cannot recursively re-enter the same critical section during execution.
If the contract is already locked, the nested invocation is rejected.
🧱 Deposit Ledger Tracking
Each deposit records the ledger/block number at which it occurred.
Soroban contract state is persisted through ledger-backed contract storage, making the deposit ledger part of the contract's authoritative state.
🚫 Same-Transaction Withdrawal Prevention
Withdrawals now require:
Therefore:
while:
This directly prevents the flash-loan pattern described in the issue.
Security Model
The protection provides two complementary safeguards:
The lock protects against recursive execution, while the ledger check enforces the required temporal separation between deposit and withdrawal.
Error Handling
The contract now explicitly rejects invalid withdrawal attempts, including:
Errors fail atomically, so rejected contract executions do not leave partial state changes behind. Soroban contract execution commits ledger modifications only after successful execution and discards them when execution traps.
Testing
Added unit coverage for both successful and rejected paths.
Happy Paths
Expected Error Paths
Tests use the Soroban local contract environment, which supports native contract testing without requiring a live network.
Acceptance Criteria
Result
The Yield-Bearing Fee Vault now has explicit protection against flash-loan-style same-transaction deposit and withdrawal attacks, combining reentrancy locking with ledger-based withdrawal enforcement while preserving normal deposits and withdrawals.
closes #729