fix: beneficiary validation, clawback access-control audit, lock_assets reentrancy docs, asset index tests (#406, #405, #398, #397) - #421
Merged
ritaifeoluwa merged 4 commits intoSep 27, 2026
Conversation
…control with tests (SmartDropLabs#406)
|
@codexhange 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! 🚀 |
✅ Deploy Preview for sdcontracts ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
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.
Description
Implements the four Stellar Wave issues (#406, #405, #398, #397) — one commit per issue. Two are code fixes; two turned out to report already-mitigated behaviour, and per this repo's own
SECURITY_FIXES.mdconvention (#357/#358/#363) those are delivered as a documented verification plus the regression tests that keep the property pinned, rather than as invented code.Related Issues
See closing references below (#406, #405, #398, #397).
Type of Change
Changes
696a603)clawbackappears nowhere insoroban/contracts/vesting-wallet/. Nothing in the contract performs a token-level clawback, so there is no unauthenticated clawback to fix.clawbackwas added on purpose — it would be a brand-new admin capability the codebase has never had, i.e. an expansion of attack surface in the opposite direction of the report, with undefined semantics (who receives the amount, interaction withreleased_amount, behaviour after revocation).SECURITY_FIXES.mdaudit section recording the finding and tabulating the authorization on every value-moving/authority-changing entry point (initialize,release,revoke,emergency_withdraw,transfer_beneficiary,transfer_admin) — all correctly gated; (2) a new regression testtest_admin_only_entry_points_require_admin_auththat authorizes no admin and asserts each admin-gated entry point is rejected with state untouched, then that the real admin still succeeds. Any future entry point missingrequire_auth()fails this test.48a08d2)VestingError::InvalidInput = 8;initializenow rejects the zero beneficiary exactly as the issue specifies, since a zero address can never signreleaseand would strand the whole vested amount.transfer_beneficiary— the same defect with the same "no recovery mechanism" impact, and the only other path that can set a beneficiary. A valid address still transfers as before.initializerejects the zero beneficiary (and mints nothing);transfer_beneficiaryrejects the zero address, leaves the old beneficiary intact, and still accepts a real one.7c78df5)unlock_ledgerand recomputedcredit_rate) is persisted beforetoken::transfer, i.e. strict checks-effects-interactions; a failed transfer traps and reverts everything. Below that, Soroban'sContractReentryModedefaults toProhibited, so a reentrant token is rejected by the host before any of our code runs.# Reentrancy posture (#398)section onlock_assetsdocumenting both layers, the transfer semantics ([security] farming-pool: lock_assets doesn't validate token transfer success #363), and the two tests that prove it, plus aSECURITY_FIXES.mdsection. No behavior change, and the two existing reentrancy tests were not modified.963f498)DataKey::AssetPools(Address) -> Vec<u32>plus the constant-timeDataKey::AssetPoolCount(Address)companion, both written by the sharedcreate_pool_inner(socreate_poolandcreate_pools_batchare covered), andget_pools_by_asset_rangereads the index first, falling back to the bounded registry scan only for records predating the index.create_pooland returns only the requested asset's pools (totalstill reports the whole registry);pool_count_by_assetagrees with the indexed lookup;create_pools_batchindexes identically to single creation; and a paginated walk resumes without dropping or duplicating indexed pools (the [bug] factory get_pools_by_asset returns next_start_id that may skip matching pools #327 resume invariant on the index path).get_pools_by_asset_rangedocstring, which still told integrators to indexpool_crtdevents for "zero-gas instant lookups" and omitted the on-chain index that now exists.#![no_std], so the test module declaresextern crate std;(same as farming-pool's tests) for thestd::vec::Vecassertions.Testing
src/test.rsper contract,security-fixeddoc convention inSECURITY_FIXES.md)Note: verification was done by code review only (no
cargobuilds in this environment, per contribution constraints); CI will runcargo test,clippy, andfmt.Closes #406
Closes #405
Closes #398
Closes #397