As of 30 Oct 2026, Fragmetric Restaking Program has 3 audit reports by 1 security firm on Trustblock; the latest is by Quantstamp, dated 8 Oct 2025. Those reports list no open critical findings.
Record last updated . It holds audits and findings, contracts and incidents up to Oct 2026. Trustblock does not review code.
Newest first
| Audit | Security firm | Date | Scope | Critical findings | Report |
|---|---|---|---|---|---|
| Fragmetric Liquid Restaking Program - 2 | Security firm: Quantstamp | Date: | Scope: Not recorded (see the report) | No open critical findings | Open · certificate.quantstamp.com |
| Fragmetric Liquid Restaking Program | Security firm: Quantstamp | Date: | Scope: Files named in the report | No open critical findings | Open · certificate.quantstamp.com |
| Fragmetric Restaking Program | Security firm: Quantstamp | Date: | Scope: Files named in the report | No open critical findings | Open · certificate.quantstamp.com |
Statuses are the security firm’s own, from each report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 0 |
| High | 0 | 0 | 2 |
| Medium | 1 | 1 | 1 |
| Low | 1 | 14 | 3 |
The function `check_withdrawal_enabled()` checks for the boolean flag `withdrawal_enabled_flag` that can be set by the admin. The flag determines if users are allowed to call the `request_withdrawal()` function. However, the flag is also checked during the final call to `withdraw()`, when users can withdraw the amount they requested after the batch is processed. This means that if the flag is set to true, users will not be able to call the function `withdraw()` even if they have an already processed amount they can claim.
Open the reportThe protocol mints receipt tokens (e.g., fragSOL) at a 1:1 ratio when the first deposit occurs: ```rust let receipt_token_mint_amount = if self.receipt_token_mint.supply == 0 { // receipt_token_mint_amount will be equal to asset_amount at the initial minting, so like either 1SOL = 1RECEIPT-TOKEN or 1SUPPORTED-TOKEN = 1RECEIPT-TOKEN. asset_amount } else { pricing_service.get_asset_amount_as_token( supported_token_mint_key.as_ref(), asset_amount, &self.receipt_token_mint.key(), )? }; ``` If the first deposited asset has a different number of decimal places than the receipt token, this could result in an incorrect exchange rate. For example: - If the first deposit is a staked SOL variant with 6 decimal places, but fragSOL expects 9 decimal places, fragSOL would be valued 1000x more than SOL, distorting its price relative to the underlying basket. However, the protocol mitigates that by having a flag that enables and disables deposits, so the protocol can be the first depositor to prevent this exploit. <br> However, the protocol includes a deposit enable/disable flag, which allows it to control when user deposits can begin. This ensures that the protocol can act as the initial depositor, setting the correct exchange rate before external deposits occur, and preventing distortions in receipt token pricing.
Open the reportIf the Jito Restaking Vault is paused, all CPI calls to it will fail, preventing the operator command cycle from advancing. This could result in a stalled execution loop where the system repeatedly attempts the same failing action. **Commands interacting with Jito Vault:** - `cmd1` → `ensure_state_update_required()` → [`close_vault_update_state_tracker()`](https://github.com/jito-foundation/restaking/blob/b096d1bf467813cde6f6f930ec2f6cc475324b28/vault_program/src/close_update_state_tracker.rs#L43) - `cmd1` → `ensure_state_update_required()` → [`initialize_vault_update_state_tracker()`](https://github.com/jito-foundation/restaking/blob/b096d1bf467813cde6f6f930ec2f6cc475324b28/vault_program/src/initialize_vault_update_state_tracker.rs#L60) - `cmd1` → `update_delegation_state()` → [`crank_vault_update_state_tracker()`](https://github.com/jito-foundation/restaking/blob/b096d1bf467813cde6f6f930ec2f6cc475324b28/vault_program/src/crank_vault_update_state_tracker.rs#L75) - `cmd3` → `withdraw()` → [`burn_withdrawal_ticket()`](https://github.com/jito-foundation/restaking/blob/b096d1bf467813cde6f6f930ec2f6cc475324b28/vault_program/src/burn_withdrawal_ticket.rs#L77) - `cmd6` → `request_withdraw()` → [`enqueue_withdrawal()`](https://github.com/jito-foundation/restaking/blob/c736bca8edc96efa603d580472b7d26c0d7224c7/vault_program/src/enqueue_withdrawal.rs#L65) - `cmd13` → `add_delegation()` → [`add_delegation()`](https://github.com/jito-foundation/restaking/blob/c736bca8edc96efa603d580472b7d26c0d7224c7/vault_program/src/add_delegation.rs#L60) - `cmd12` → `deposit()` → [`update_vault_balance()`](https://github.com/jito-foundation/restaking/blob/c736bca8edc96efa603d580472b7d26c0d7224c7/vault_program/src/update_vault_balance.rs#L38) - `cmd12` → `deposit()` → [`mint_to()`](https://github.com/jito-foundation/restaking/blob/b096d1bf467813cde6f6f930ec2f6cc475324b28/vault_program/src/mint_to.rs#L75)
Open the reportCurrently, the protocol relies on multiple pricing sources to fetch the price of the different assets it supports for deposits and withdrawals. Supported tokens that use Orca DEX as a pricing source retrieve the spot price instead of a time-weighted average price (TWAP). The configuration of the fund hedges volatility by doing the following: ```Price of FragJito = (JTO Price * JTO Reserve In fund) / FragJTO = JTO Price * K``` However, it should be noted that highly volatile tokens can be vulnerable to flash loan attacks to manipulate the spot price. Since only the JTO token uses the spot price and JTO is the only supported token for FragJTO, this is not currently a risk. The flash loan attack becomes viable if a supported token that uses a spot price is not the only token in a fund account.
Open the reportThe admin has the ability to set a withdrawal fee rate. This value is stored in basis points, which means that a rate of `1` is equal to a 0.01% fee. There are no restrictions on the value the admin can set. This includes the ability to set withdrawal rates above 100% which would block withdrawals. In order to make users feel more secure and prevent the admin from disabling withdrawals via the rate, it is recommended to enforce a maximum allowed rate.
Open the report1. In `user_fund_supported_token_context.rs`, function `deposit_supported_token()`, when emitting the event `UserDepositedSupportedTokenToFund`, it should be clarified if `fund_account` should be created with the values of `receipt_token_price` and `receipt_token_total_supply` before or after the deposit is recorded. 2. In `user_fund_context.rs`, function `deposit_sol()`, when emitting the event `UserDepositedSOLToFund`, it should be clarified if `fund_account` should be created with the values of `receipt_token_price` and `receipt_token_total_supply` before or after the deposit is recorded. 3. In `user_receipt_token_transfer_context.rs`, function `handle_transfer()`, when emitting the `UserTransferredReceiptToken`, it should be clarified if `source_fund_account` and `destination_fund_account` should use placeholders created with the address of the funds, or with the address of the underlying users. 4. In `operator_fund_context.rs`, function `process_fund_withdrawal_job()`, when emitting the event `OperatorProcessedJob`, it should be clarified if `fund_account` should be created with the values of `receipt_token_total_supply` before or after the withdrawal is recorded.
Open the reportIn `user_fund_context.rs`and the function `withdraw()`, if accounting discrepancies occur, no check prevents withdrawing all lamports from `fund_account`, which would result in the deletion of the account's data.
Open the reportThe protocol implements a withdrawal flow, where a user has to first request a withdrawal, through the `request_withdrawal()`, and then it has to be processed along with other withdrawal requests, if any. To process withdrawal requests, the operator needs to either wait for a pre-determined amount of time between each batch (`batch_processing_threshold_duration`), or a threshold amount (`batch_processing_threshold_amount`). This means that a user with a high stake, that is greater than `batch_processing_threshold_amount` can deposit and withdraw instantly.
Open the reportIn all but one case, the global `RewardPool` is always updated alongside the `UserRewardPool`. During deposits and withdrawals for instance. However, there is one case where a `UserRewardPool` will be updated without updating the `RewardPool` it is part of, namely this is the `update_user_reward_pools()` function that is callable by any user. There are no specific issues that are related to this case, but it might cause issues down the line if some future functionality expects the `UserRewardPool` and `RewardPool` to be updated together.
Open the report**Description** It is important to validate inputs, even if they only come from trusted addresses, to avoid human error: 1. In `update.rs`, it is possible to call `add_holder()` with: a) an empty vector `pubKeys`; b) a vector `pubKeys` containing duplicates; 2. In `fund_manager_fund_supported_token_context.rs`, we can have in `FundManagerFundSupportedTokenContext` the following equality: `receipt_token_mint == supported_token_mint`. 3. In `user_fund_supported_token_context.rs`, function `deposit_supported_token()` and in `user_fund_context.rs`, function `deposit_sol()`, the values of `metadata` (`wallet_provider` and `contribution_accrual_rate`) are not sanitized. 4. In `fund_manager_fund_context.rs`, we can use: a) in `update_sol_withdrawal_fee_rate()` any value for `sol_withdrawal_fee_rate`; b) in `update_batch_processing_threshold()` any value for `amount` and `duration`; 5. It is possible to execute the instruction `fund_manager_settle_reward()` for an `amount` of `0`, which can create a `RewardSettlementBlock` of `amount == 0`.
Open the reportThe protocol allows the deposit of a set of supported assets, or simply `SOL`, in exchange for `fragSol`. When users want to withdraw, they will get an amount of `SOL` that is equivalent to the `fragSol` value at the time of withdrawal. However, **there is no functionality for the admin to withdraw the supported tokens deposited by the users**. The protocol will not allow withdrawal at its first stage, which mitigates the risk that users might withdraw all the `SOL` deposited and leave the other supported tokens.
Open the reportThe functions `init_without_load()` and `bump()` access the value of `data` at a given `offset`. However, no check makes sure that `offset` is not an out-of-bound ID.
Open the reportThe closure `is_contribution_accrual_rate_valid` currently checks if the rate is invalid (i.e., not in the range `100..200`), so the closure name is misleading.
Open the reportThe protocol tracks `fragSol` transfers using a custom transfer hook. Currently, the feature is disabled, and transfers are not allowed. However, the transfer hook does not perform an allocation update for the source and the destination. This means if transfers were to be enabled, specifically in the function `UserReceiptTokenTransferContext.handle_transfer()` the balances and rewards of the source and destination will remain the same.
Open the reportAn underflow error can happen without explicit error if a user executes a transaction with `user_deposit_sol()` or `user_deposit_supported_token()` as the first instruction with `metadata`. In this case, the variable `current_ix_index` in the function `verify_preceding_ed25519_instruction()` will take the value `0`, and underflow will happen at the line: ``` let ix = instructions::load_instruction_at_checked(current_ix_index - 1, instructions_sysvar)?; ```
Open the reportThe reports name a repository or files. Open a report to see its scope.
Is this your project? Show this record on your own website. The label states what the record holds, links to this page and updates by itself. It is free and needs no sign-in.
Automatic: the three strongest facts of this project’s own record (its last audit and two more), highlighted. They update with the record. Picking a fact turns Automatic off.
<head><script src="https://widget.trustblock.run/project-widget.min.js" defer></script></head><body><divdata-tb-project-widgetdata-tb-project-slug="fragmetric-restaking-program"></div></body>
Paste the code where the label should appear. It uses no API credit and updates by itself.
Something wrong on this page? A missing report, a wrong date, a finding that was fixed since. Tell us and we check it against its source.
Tell us