Prepared by:
HALBORN
Last Updated 08/12/2026
Date of Engagement: June 5th, 2026 - July 8th, 2026
100% of all REPORTED Findings have been addressed
All findings
67
Critical
1
High
0
Medium
10
Low
35
Informational
21
This security assessment was commissioned by Splyce, a permissionless institutional yield protocol built on Stellar/Soroban that offers fixed rate, fixed term lending vaults backed by tokenized real world assets alongside a yield bearing stablecoin product. The review was conducted by Halborn's experienced security team, focusing on the on-chain components of the Splyce S-Token smart contract suite. The assessment covered all functionality within the SToken, Factory, Accountant, NavOracle, FixedYieldOracle, ProxyAssetManager, Multisig, ThresholdPolicy, and Ed25519Verifier contracts from June 5th, 2026, to July 8th, 2026. The primary objective of this engagement was to identify potential vulnerabilities, verify module reliability, and enhance the overall security posture of the protocol.
Halborn's security team dedicated significant effort to verifying the security of the smart contracts, combining manual code review, control flow analysis, and targeted proof of concept validation across the vault, governance, and oracle layers of the protocol.
The purpose of this assessment is to:
Ensure that smart contract functions operate as intended
Identify potential security issues within the smart contracts
In summary, Halborn identified some improvements to reduce the likelihood and impact of risks, which were completely addressed by the Splyce team. The main recommendations were the following:
Redesign asset custody and liquidity accounting around the ProxyAssetManager. A single vault binding permanently strands underlying funds belonging to a sibling vault after a cross-vault swap or asset manager rotation, and a separate emergency sweep path bypasses total_idle accounting entirely. Both undermine the guarantee that vault funds remain recoverable and correctly tracked on-chain, and together represent the most severe risk identified in this engagement.
Close the pending-price arbitrage window across vault operations. Large price deviations are queued for manager review instead of being rejected, but deposits, withdrawals, and swaps can still execute against a stale accepted price while a more accurate pending price awaits acceptance, creating a risk-free arbitrage opportunity that a user can exploit before the price is corrected.
Harden the yield oracles against manipulation and denial of service. NavOracle's fee accrual function can be called by anyone to repeatedly block legitimate price updates, and FixedYieldOracle's linear time-based price curve allows early depositors to capture value from later depositors while retroactive rate changes can produce discontinuous price jumps; both designs need stronger economic and access-control safeguards.
Correct management fee accrual and fee distribution accounting. Zero-accrual calls silently advance the accrual timestamp and suppress fees the protocol is owed, and the Accountant contract cannot distribute fee shares for any vault whose share token differs from the one set at initialization, permanently stranding fee income from secondary vaults sharing the same Accountant.
Align token behavior with ERC-4626 and SEP-41 expectations. Whitelist checks validate only the caller on deposit and withdrawal paths, allowing a whitelisted user to route shares or underlying funds to a non-whitelisted receiver, and burn events are emitted before the underlying withdrawal request actually completes, misrepresenting when tokens are destroyed.
Harden storage-dependent safeguards against expiry and unbounded growth. The factory's vault registry is stored as a single unbounded list that will eventually exceed the instance storage limit and permanently block new vault deployments.
| Security analysis | Risk level | Remediation |
|---|---|---|
| ProxyAssetManager Single-Vault Binding Permanently Strands Swap-Sibling Funds | Critical | Solved - 07/22/2026 |
| Pending Price Window Enables Risk-Free Arbitrage Across All Vault Operations | Medium | Solved - 07/22/2026 |
| FixedYield Time-Based Price Curve Enables First-Mover Principal Drain | Medium | Risk Accepted - 07/22/2026 |
| FixedYieldOracle Retroactive Rate Application Causes Discontinuous Price Jumps | Medium | Solved - 07/22/2026 |
| Accept Allowlist Mint Skips Deviation And Staleness Parity | Medium | Solved - 07/22/2026 |
| Unbounded Vaults Vec in Instance Storage Creates Permanent Factory DoS | Medium | Solved - 07/22/2026 |
| Unpermissioned Fee Accrual Enables Persistent DoS on NavOracle Price Updates | Medium | Solved - 07/22/2026 |
| Accountant.distribute_tokens Strands Fee Shares From Secondary Vaults | Medium | Solved - 07/22/2026 |
| ERC-4626 Receiver Address Bypasses Whitelist Controls On Deposit And Withdrawal Paths | Medium | Solved - 07/22/2026 |
| Swap Reads Accepted Price, Ignoring Pending Downward Price Drop | Medium | Solved - 07/22/2026 |
| Emergency Sweep Bypasses Vault total_idle Accounting | Medium | Solved - 07/22/2026 |
| Management Fee Accrues During Pause Diluting Locked Shareholders | Low | Solved - 07/22/2026 |
| Swap Fee Read Only From Source Vault Enables Fee Avoidance | Low | Solved - 07/22/2026 |
| Late-Cancel Penalty Mints Free Shares Via Unfulfilled Withdrawal Requests | Low | Solved - 07/22/2026 |
| Price Staleness Check Bypassed Until First Oracle Update | Low | Solved - 07/22/2026 |
| NAV Oracle Raw Balance Enables Donation Price Manipulation | Low | Solved - 07/22/2026 |
| Management Fee Dilution Formula Uses Wrong Denominator | Low | Solved - 07/22/2026 |
| Zero-Accrual Management Fee Calls Advance Timestamp, Suppressing Revenue | Low | Solved - 07/22/2026 |
| Upgrader Role Never Granted, All Contracts Permanently Non-Upgradeable | Low | Solved - 07/22/2026 |
| Swap Mints Destination Shares Without Backing Underlying Transfer | Low | Risk Accepted - 07/22/2026 |
| Unstructured panic!() Obscures Runtime Errors In Core Token Functions | Low | Solved - 07/22/2026 |
| Emergency Withdraw Skips total_idle Decrement, Breaking Vault Accounting | Low | Solved - 07/22/2026 |
| Zero Cooldown Bypasses Two-Step Governance in Three Contracts | Low | Solved - 07/22/2026 |
| Unilateral Role Transfers Allow Assignment Without Incoming Holder Consent | Low | Solved - 07/30/2026 |
| NavOracle Price Omits Decimals Offset Scaling | Low | Solved - 07/22/2026 |
| Unguarded initialize() Enables Front-Running in Four Contracts | Low | Solved - 07/22/2026 |
| Process Deposits Deploys Funds Reserved for Pending Withdrawals | Low | Solved - 07/22/2026 |
| Post-Mint Re-Addition Inflates VaultTotalSharesUpdated Swap Event | Low | Solved - 07/22/2026 |
| Premature Burn Event In burn() Mismatches Actual Destruction | Low | Solved - 07/22/2026 |
| Oracle grant_role Override Absent Bypasses Timelocked Provider Rotation | Low | Solved - 07/22/2026 |
| Management Fee Mint Bypasses Total Shares Cap | Low | Solved - 07/22/2026 |
| Emergency Withdraw Pays Manager Not Depositors | Low | Solved - 07/22/2026 |
| Factory Constructor Accepts Zero WASM-Hash Cooldown, Permanently Voiding Timelock | Low | Solved - 07/22/2026 |
| Initialize Accepts Zero Cooldowns Bypassing All Timelocks | Low | Solved - 07/22/2026 |
| Multisig Signer Removal Causes Permanent Account Lockout | Low | Solved - 07/11/2026 |
| max_deviation_bps Zero Disables Oracle Price Deviation Guard | Low | Solved - 07/22/2026 |
| Instant Single-Key WASM Upgrade Bypasses All Governance Timelocks | Low | Solved - 07/22/2026 |
| Manager Can Drain Vault Funds Without Adequate Delay Controls | Low | Risk Accepted - 07/22/2026 |
| Multisig CallContract Rules Scope To Entire Contract | Low | Solved - 07/22/2026 |
| WASM Hash Proposal Silently Overwritable With No Cancel Path | Low | Solved - 07/22/2026 |
| Asset Manager Rotation Strands Externally Deployed Funds | Low | Solved - 07/22/2026 |
| 100% System Penalty Ceiling Enables Unbounded Share Dilution on TTL Cancel | Low | Solved - 07/22/2026 |
| ProxyAssetManager Init Cooldowns Unvalidated, Zero Value Permanently Voids Governance | Low | Solved - 07/22/2026 |
| Silent i128-to-u64 Casts Break Balance And Fee Accounting | Low | Solved - 07/22/2026 |
| propose_cooldowns Missing pending_withdrawal_params Guard Shortens Timelock | Low | Solved - 07/01/2026 |
| propose_limits No-Op Guard Omits min_shares_to_mint, Silently Rejects Valid Proposals | Low | Solved - 07/22/2026 |
| NatSpec Promises Compound Interest But Implementation Uses Simple Interest | Informational | Solved - 07/22/2026 |
| BUMP_THRESHOLD Off-by-28-Days Causes ~29x More Frequent TTL Extensions Than Intended | Informational | Solved - 07/22/2026 |
| Stale Caller Address in Role-Change Events During Combined Manager and Multi-Role Rotation | Informational | Acknowledged - 07/22/2026 |
| NavOracle Price Update Cooldown Not Enforced | Informational | Acknowledged - 07/22/2026 |
| Multisig Constructor Allows Deployment Without Threshold Policy | Informational | Solved - 07/22/2026 |
| Accountant Fee Redirect Bypasses Governance Timelock | Informational | Solved - 07/22/2026 |
| Rogue Manager Blocks Cooldown Changes via Perpetual Re-Proposal | Informational | Solved - 07/22/2026 |
| Unsafe i128-to-u64 Cast Corrupts NAV Oracle Price | Informational | Solved - 07/22/2026 |
| Accountant.distribute_xlm Uses Unchecked Arithmetic Unlike distribute_tokens | Informational | Solved - 07/22/2026 |
| Multisig add_signer Silently Weakens M-of-N Threshold | Informational | Acknowledged - 07/22/2026 |
| ProxyAssetManager Initialize Skips Underlying Asset Validation | Informational | Solved - 07/22/2026 |
| Duplicate Signer Key Onboardable Via Second Verifier | Informational | Solved - 07/22/2026 |
| Pending Price Path Skips Cooldown Write, Enabling Repeated Overwrite | Informational | Solved - 07/22/2026 |
| Propose Limits Skips Min-Max Cross Validation | Informational | Solved - 07/22/2026 |
| Cancel Withdrawal Blocked During Vault Pause | Informational | Solved - 07/22/2026 |
| Auto-Apply Band Allows Unbounded Cumulative Oracle Price Drift | Informational | Acknowledged - 07/22/2026 |
| ProxyAssetManager.propose_processor Accepts Identical Processor Causing No-Op Role Cycle | Informational | Solved - 07/22/2026 |
| Asset.mint Accepts Non-Positive Amounts Without Validation | Informational | Solved - 07/22/2026 |
| Whitelist and AllowlistMint Reads Missing TTL Bump Risk Entry Archival and Restoration Overhead | Informational | Solved - 07/22/2026 |
| Unpause Leaves Stale Emergency Withdrawal Request in Storage | Informational | Solved - 07/22/2026 |
| Dead Comparison on u64 Obscures Zero-Elapsed-Time Guard | Informational | Solved - 07/22/2026 |
Halborn strongly recommends conducting a follow-up assessment of the project either within six months or immediately following any material changes to the codebase, whichever comes first. This approach is crucial for maintaining the project’s integrity and addressing potential vulnerabilities introduced by code modifications.
// Download the full report
Smart Contract Assessment
* Use Google Chrome for best results
** Check "Background Graphics" in the print settings if needed