Pluto security record

As of 15 Oct 2026, Pluto has 2 audit reports by 2 security firms on Trustblock; the latest is by Cyberscope, dated 27 Feb 2025. Those reports list no open critical findings. It also holds 1 deployed contract on 1 chain and 1 incident (latest 1 Jan 2021).

Critical findings
No open critical findings
Across 2 reports.
Incident
Incident 1 Jan 2021
Source: De.Fi incident database. 2 audits have been published since. See the incident
Open the latest report
Your label, live
Get the label for your site

Record last updated . It holds audits and findings, contracts and incidents up to Oct 2026. Trustblock does not review code.

Audits2

Newest first

AuditSecurity firmDateScopeCritical findingsReport
PlutoSecurity firm: CyberscopeDate: Scope: 1 address on BNB ChainNo open critical findingsOpen · cyberscope.io
PlutoSecurity firm: QuillAuditsDate: Scope: Files named in the reportNo open critical findingsOpen · quillaudits.com

Findings14

Statuses are the security firm’s own, from each report.

SeverityOpenAcknowledgedFixed
Critical000
High206
Medium000
Low105
HighIncorrect Calculation of Thirty-Minute APRPluto · QuillAudits · 4 Nov 2024Fixed

The function handle in earn_vault_set_index & leverage_vault_set_index calculates the thirty_minute_apr based on the hourly_apr. This value is derived from higher APR values (e.g., hourly APR or daily APR) and is used in subsequent computations for updating vault indices. However, in both cases, the formula used to compute the thirty_minute_apr is flawed. The error affects downstream computations such as gain, borrow_gain resulting in incorrect indices.let thirty_minute_apr = decimals::div_ceil(     INDEX_DECIMALS,      hourly_apr,      INDEX_DECIMALS,      3,      0)?;

Open the report
HighIncorrect Implementation of div_floor, div_ceil, mul_floor, and mul_ceilPluto · QuillAudits · 4 Nov 2024Fixed

The functions div_floor, div_ceil, mul_floor, and mul_ceil are designed to perform fractional arithmetic while applying either flooring or ceiling logic. However, upon closer inspection, the current implementation relies entirely on Rust's default behavior for division and multiplication without explicitly enforcing flooring or ceiling logic.No Explicit Logic for Floor or Ceil: The functions div_floor and div_ceil use the same logic and rely on Fraction::checked_div, which inherently performs truncation (flooring) in Rust for integers. There is no additional logic to enforce ceiling behavior. Similarly, mul_floor and mul_ceil behave identically because there is no logic to enforce rounding up or down. Potential for Incorrect Results: In cases where explicit ceiling behavior is required (e.g., rounding up fractional results), the current implementation will fail to deliver the expected results as the entire protocol is heaviliy dependednt on it.

Open the report
HighIncorrect time_diff Calculation Prevents EMA Updates in Rate StructPluto · QuillAudits · 4 Nov 2024Fixed

The update_rate function in the Rate struct is indirectly called through the set_index methods in both earn_vault_set_index and leverage_vault_set_index. However, due to the bug in update_rate where time_diff always evaluates to 0, the EMA calculations for both APY and borrowing APY will fail to update, rendering the functionality ineffective.This can have the following implications:  1. Stale Rate Metrics: Both the hourly and daily EMA values remain uninitialized or outdated, misrepresenting the APY and borrowing APY trends.  2. Protocol Inaccuracy: Any logic depending on these rates, such as user-facing metrics or borrowing/lending terms, could behave incorrectly or mislead users.

Open the report
HighLiquidation Fee Bypass via Improper Instruction SequencingPluto · QuillAudits · 4 Nov 2024Fixed

The protocol's liquidation mechanism involves several sequential instructions, such as LeverageVaultKeeperRepayBorrow, LeverageVaultKeeperPayLiquidationFee, and LeverageVaultKeeperClosing. These instructions handle key operations such as repaying borrow amounts, paying liquidation fees, and closing positions. If the correct sequence of instructions is not enforced, liquidation fees can be bypassed

Open the report
HighMisleading Index Growth Due to Time-Based Updates in Earn and Leverage VaultsPluto · QuillAudits · 4 Nov 2024Fixed

The update_rate function is invoked by calling the functions earn_vault_set_index & leverage_vault_set_index and has the following code respectively.// earn_vault_set_index() pub fn set_index(&mut self, last_index_updated: i64, index: u128, apy: u32) -> Result<()> {     require!(index > 0, Errors::InvalidAmountZero);     self.index = index;     self.last_index_updated = last_index_updated;     self.apy.update_rate(apy, self.last_index_updated)?;     Ok(()) } Here, the update_rate function updates the APY rate and calculates the exponential moving averages (EMAs) over time intervals like hourly, daily, and beyond, based on the last_index_updated timestamp. // leverage_vault_set_index() pub fn set_index(&mut self, last_index_updated: i64, index: u128, apy: u32, borrowing_index: u128, borrowing_apy: u32) -> Result<()> {     require!(index > 0, Errors::InvalidAmountZero);     require!(borrowing_index > 0, Errors::InvalidAmountZero);     self.last_index_updated = last_index_updated;     self.index = index;     self.borrowing_index = borrowing_index;     self.apy.update_rate(apy, self.last_index_updated)?;     self.borrowing_apy.update_rate(borrowing_apy, self.last_index_updated)?;     self.update_time()?;     Ok(()) }

Open the report
HighMissing Validation on leverage_vault in earn_vault_set_index Function Allows Arbitrary Data LoadingPluto · QuillAudits · 4 Nov 2024Fixed

The function handle in earn_vault_set_index operates on multiple accounts, including the leverage_vault. The leverage_vault account is passed into the function, and data is loaded from it to compute important metrics such as leverage_apy and other vault-related calculations The leverage_vault account lacks proper validation, which means any arbitrary vault can be passed as the leverage_vault parameter. If a malicious or incorrect vault is passed, the function will load and operate on unintended or invalid data, leading to incorrect calculations, protocol inconsistencies.

Open the report
LowEvent Emission in earn_vault_withdraw can be OptimizedPluto · QuillAudits · 4 Nov 2024Fixed

The function earn_vault_withdraw emits two events, EventEarnWithdraw and EventEarnWithdrawn, which contain overlapping information. This redundancy increases transaction size and storage costs on Solana.

Open the report
LowParameter Naming for Price Oracle Functions Can Be Improved to Enhance ClarityPluto · QuillAudits · 4 Nov 2024Fixed

The functions leverage_vault_create, leverage_vault_change_price_oracle, and earn_vault_change_price_oracle contain misleading parameter names, causing confusion:1. leverage_vault_create: The parameters token_collateral_decimal and native_collateral_decimal in handler_vault_leverage_create::handle imply they are decimals but actually represent price feed data for token and native collateral. 2. leverage_vault_change_price_oracle: The parameters token_collateral_decimal and native_collateral_decimal in handler_vault_leverage_change_price_oracle::handle also suggest decimals but are price feed data.earn_vault_change_price_oracle: The parameter token_decimal in handler_vault_earn_change_price_oracle::handle implies a decimal value but is actually price feed data for a token.

Open the report
LowProtocol Fees in earn_config_set not validatedPluto · QuillAudits · 4 Nov 2024Fixed

The earn_config_set function does not validate critical fee parameters (protocol_fee, deposit_fee, withdraw_fee, and borrow_fee). Without these validations, it is possible to set unreasonable values (e.g., extremely high or negative fees), which could disrupt the protocol and lead to misconfigurations.

Open the report
LowRefactoring update_rate can improve code readability & save gasPluto · QuillAudits · 4 Nov 2024Fixed

The update_rate function in the provided code has a high level of redundant operations and repetitive calculations that can be optimized to save storage and compute resources when deployed on Solana

Open the report
Show 1 more
LowUnnecessary Lamport Balance Check in unwrap_sol FunctionPluto · QuillAudits · 4 Nov 2024Fixed

The function unwrap_sol contains an unnecessary check for the user's SOL lamport balance:require_gte!(user.lamports(), amount, Errors::InsufficientFunds); This check is irrelevant as the function only deals with WSOL tokens and their associated accounts, not the user's lamport balance.

Open the report

Incidents1

Attached through a shared contract address. Our incident data ends in Oct 2026.

Incident

Incident,

The contract owner could disable the transfer function, which restricted users in selling their tokens.

Source: De.Fi incident database.

Audits before it
0.
Audits since
2, the latest dated 27 Feb 2025.

Contracts1

AddressChainSource code
0x409cf201e81fc1e8538eb329e20a8513fcee996cChain: BNB ChainSource code: Verified source

All 1 address and the files the reports name

Show this on your site

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.

Content

Facts

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.

Fixed as
Language

Style

Layout
Theme
Accent
Corners

Format

Size
Date
Embed as
HTML
<head>
<script src="https://widget.trustblock.run/project-widget.min.js" defer></script>
</head>
<body>
<div
data-tb-project-widget
data-tb-project-slug="pluto"
></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