Low Findings


Boundary Check for Minimum Borrow Amount

Severity: Low

Ecosystem: Sui

Protocol: Creek Finance

Auditor: MoveBit

Report: https://movebit.xyz/reports/Creek-Audit-Report-2025-12-30.pdf

Report Date: Dec 2025

Description:

In borrow_internal, the condition excludes the valid edge case where the borrow amount equals the minimum allowed value plus the fee.


One-way ownership transfer pattern is Unsafe

Severity: Low

Ecosystem: Supra Chain

Protocol: Dexlyn Hyperlane

Auditor: Hacken

Report: https://hacken.io/audits/dexlyn/sca-dexlyn-hyperlane-monorepo-dec2024/

Report Date: Dec 2024

Description:

In router.movemailbox.move, and multisig_ism.move, the ownership transfer pattern implemented in functions like transfer_ownership() uses a single-step process where ownership is directly transferred to a new address. If the new owner address is incorrectly specified (typo, wrong address format, etc.), ownership could be permanently lost with no way to recover.


In an edge case transfer will revert despite having sufficient funds

Severity: Low

Ecosystem: Supra Chain

Protocol: Dexlyn Hyperlane

Auditor: Hacken

Report: https://hacken.io/audits/dexlyn/sca-dexlyn-hyperlane-monorepo-dec2024/

Report Date: Dec 2024

Description:

In move/igps/sources/igps.move, the pay_for_gas function's balance check uses a strict greater than (>) comparison instead of greater than or equal to (>=). This causes transactions to revert when a user has exactly the required amount:

assert!(coin::balance<AptosCoin>(account_address) > required_amount, ERROR_INSUFFICIENT_INTERCHAIN_GAS);

Transactions will fail even when users have exactly the required amount of funds to pay for interchain gas. While not a security vulnerability, this creates unnecessary friction and may confuse users who have allocated precisely the required amount.


Zero-Stake Period Leads to Reward Loss

Severity: Low

Ecosystem: IOTA Mainnet

Protocol: Pools Finance

Auditor: Hacken

Report: https://hacken.io/audits/pools-finance/sca-pools-finance-pools-contracts-may2025/

Report Date: June 2025

Description:

A vulnerability exists in the staking protocol's reward accumulation mechanism that causes permanent loss of rewards during periods when no users have staked tokens. The issue stems from the protocol's division-by-zero protection logic that returns zero accumulated rewards when total_staked 0, effectively discarding rewards that should be distributed to future stakers.


Bug in condition when checking we borrowed enough

Severity: Low

Ecosystem: Sui

Protocol: Kai Finance

Auditor: Asymptotic

Report: https://info.asymptotic.tech/kai-leverage-verification-report-6ec808dd2adc4b55a4e30f0512260a70

Report Date: Aug 2024

Description:

It checks for borrowed_x while the function refers to position y(github) . It is not critical because create_position rechecks correctly.


Incorrect treasury empty check

Severity: Low

Ecosystem: Sui

Protocol: Kai Finance

Auditor: Asymptotic

Report: https://info.asymptotic.tech/kai-leverage-verification-report-6ec808dd2adc4b55a4e30f0512260a70

Report Date: Aug 2024

Description:

The treasury check is incomplete in add_lend_facil (github). The condition should be registry.supply_x64() == 0 && registry.underlying_value_x64() == 0 .

create_pool is an example of the correct condition (github).

Not major because it is a function used by the owner of the pool — it just protects against silly mistakes.


Can delete non-empty action group

Severity: Low

Ecosystem: Sui

Protocol: Aeon

Auditor: Asymptotic

Report: https://info.asymptotic.tech/aeon-audit-report#262c1aef2c7042b7816a0015ed4a0051

Report Date: Feb 2025

Description:

execute_config_delete_action_group, does not assert that the group is empty, like execute_config_user_delete_group and execute_config_address_book_delete_group


view_mpc_ready_signing_tx_signable is a getter/viewer so it shouldn't have any asserts

Severity: Low

Ecosystem: Sui

Protocol: Aeon

Auditor: Asymptotic

Report: https://info.asymptotic.tech/aeon-audit-report#262c1aef2c7042b7816a0015ed4a0051

Report Date: Feb 2025

Description:

Can they be moved in process_module_action_result or create_module_action_result?


Cosmos transactions cannot be updated

Severity: Low

Ecosystem: Sui

Protocol: Aeon

Auditor: Asymptotic

Report: https://info.asymptotic.tech/aeon-audit-report#262c1aef2c7042b7816a0015ed4a0051

Report Date: Feb 2025

Description:

In aeon-chains/sources/cosmos_module.move, prepare_signing doesn’t call add_transaction as it should, which means that prepare_signing_accelerate calls get_transaction_borrow_mut and fails.


Missing check in process_vault_module_changes

Severity: Low

Ecosystem: Sui

Protocol: Aeon

Auditor: Asymptotic

Report: https://info.asymptotic.tech/aeon-audit-report#262c1aef2c7042b7816a0015ed4a0051

Report Date: Feb 2025

Description:

In custody/sources/vault.move, process_vault_module_changes should assert!(added_chain_state_data_id_opt.is_some(), EMissingChainState), like the existing assert!(updated_chain_state_data_id_opt.is_some(), EMissingChainState)


set_manager incorrectly logs old manager

Severity: Low

Ecosystem: Sui

Protocol: Bluefin RFQ

Auditor: Asymptotic

Report: https://bluefin.io/blog/doc/bluefin_rfq_audit.pdf

Report Date: Feb 2025

Description:

let old_manager = manager; actually records the new manager instead of the old one.


Incorrect Cooldown Check in withdraw Function

Severity: Low

Ecosystem: Sui

Protocol: SatLayer Sui

Auditor: Asymptotic

Report: https://info.asymptotic.tech/satlayer-audit

Report Date: Mar 2025

Description:

The withdraw function uses an incorrect comparison operator when validating if the cooldown period has passed. The current implementation uses a strict greater than (>) operator, which could lead to users being unable to withdraw their funds at the exact moment when the cooldown period expires.


Executed Orders Cleanup Missing

Severity: Low

Ecosystem: Sui

Protocol: ZO Perps(Sudo)

Auditor: Asymptotic

Report: https://info.asymptotic.tech/sudo-audit-report

Report Date: Mar 2025

Description:

The functions clear_open_position_order and clear_decrease_position_order are the only ones that remove orders from market.orders bag. They handle order cancellation by users (requiring OrderCap) and return their fee and collateral. Users don't need to execute these functions and pay gas fees for already executed orders. As a result, executed orders—both successful and failed—remain permanently stored in market.orders without any cleanup mechanism.


Incorrect Collateral Sufficiency Check in update_emission

Severity: Low

Ecosystem: Sui

Protocol: Full Sail CLMM

Auditor: Asymptotic

Report: https://info.asymptotic.tech/full-sail-clmm-audit

Report Date: May 2025

Description:

The update_emission function in rewarder module checks collateral sufficiency using RewarderGlobalVault::balances instead of available_balance. Since balances includes already settled but unclaimed rewards, this validation is unreliable and could lead to insufficient actual collateral for new emissions.

The daily rewards calculation 86400 * (emission_rate >> 64) performs the shift before multiplication, leading to potential precision loss due to truncation of emission_rate.

The code uses hardcoded literals (86400) instead of named constants.


fetch_ticks Behavior Deviates from Other Fetch Functions

Severity: Low

Ecosystem: Sui

Protocol: Full Sail CLMM

Auditor: Asymptotic

Report: https://info.asymptotic.tech/full-sail-clmm-audit

Report Date: May 2025

Description:

The fetch_ticks function in the tick module behaves inconsistently compared to other fetch_* functions.

It skips the tick at tick_indexes[0] itself, starting from the next tick(include parameter in find_next function is set to false). This differs from other fetch functions, which typically include the starting element, and can lead to unexpected omissions or developer confusion.

Additionally, fetch_ticks function does not check the limit in the while loop condition, only inside the loop body. As a result, if the limit is set to zero, the loop still runs and continues fetching until the end of the list, since the break condition if (new_count == limit) is never satisfied. While a limit of zero could be interpreted as "fetch all", this behavior is not aligned with the comments or how limits are handled in similar functions.


repay_flash_swap Ignores partner_id

Severity: Low

Ecosystem: Sui

Protocol: Full Sail CLMM

Auditor: Asymptotic

Report: https://info.asymptotic.tech/full-sail-clmm-audit

Report Date: May 2025

Description:

repay_flash_swap called after flash_swap_with_partner ignores the partner_id, but this is not an issue, because it checks that ref_rate == 0. Still, I would recommend to change the type of partner_id in FlashSwapReceipt to Optionsui::object::ID, and in repay_flash_swap check that it is None.


Pause bypass for reward updates

Severity: Low

Ecosystem: Sui

Protocol: Momentum

Auditor: Sherlock

Report: https://1760493472-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FvMYfd5Y4I2ZxHbqdOD88%2Fuploads%2FCoI611HTaCx34uzF6O8j%2F2025_11_12_Final_Momentum_Collaborative_Audit_Report_1762918494.pdf?alt=media&token=216a66b1-491d-405a-a57f-b1b9f530ab78

Report Date: Nov 2025

Description:

The admin entry points uses a pause flag on VeMMT to freeze critical state changes during incidents. Functions that initialize a schedule or extend its duration explicitly check is_paused and abort when true. The emission returning function like update_pool_reward_emission lacks this guard and still calls into the pool to update rate and end-time accounting.


The get_user_claim_reward_amount overestimates claimable reward

Severity: Low

Ecosystem: Sui

Protocol: Momentum

Auditor: Sherlock

Report: https://1760493472-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FvMYfd5Y4I2ZxHbqdOD88%2Fuploads%2FCoI611HTaCx34uzF6O8j%2F2025_11_12_Final_Momentum_Collaborative_Audit_Report_1762918494.pdf?alt=media&token=216a66b1-491d-405a-a57f-b1b9f530ab78

Report Date: Nov 2025

Description:

The read path computes the user’s claim by iterating epochs and calculating each epoch’s accrual from index deltas and vote power. For each epoch, it caps the computed value by the current pool balance. Because it does not model a running “remaining pool balance,” it may cap multiple epochs against the same balance snapshot and sum a total larger than the coin the pool can transfer atomically. Additionally, the view reads time-sensitive fields like current index or end-of-epoch markers without first calling the pool’s sync_or_advance_epoch sync routine, so the calculation can be stale within an epoch.


View helpers abort for unstaked ve-tokens

Severity: Low

Ecosystem: Sui

Protocol: Momentum

Auditor: Sherlock

Report: https://1760493472-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FvMYfd5Y4I2ZxHbqdOD88%2Fuploads%2FCoI611HTaCx34uzF6O8j%2F2025_11_12_Final_Momentum_Collaborative_Audit_Report_1762918494.pdf?alt=media&token=216a66b1-491d-405a-a57f-b1b9f530ab78

Report Date: Nov 2025

Description:

The build_ve_token_data view builder composes a position object by pulling claimable rewards, last-claimed markers, and other reward fields via helpers that borrow the UserRe wardData dynamic field from the VeToken. That dynamic field exists only for staked tokens that have been deposited through deposit. The builder computes “staked or not” later in the flow using is_ve_staked, so the early attempt to borrow UserRewardData on an unstaked token aborts the view call. Read-only endpoints that rely on build_ve_token_data inherit the same failure mode.


Initialization Function Can be Called Multiple Times

Severity: Low

Ecosystem: Sui

Protocol: Momentum

Auditor: MoveBit

Report: https://1760493472-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FvMYfd5Y4I2ZxHbqdOD88%2Fuploads%2FKo0UYHCVcSEui2ZTJSA6%2FMMT Audit Report-2025-11-13.pdf?alt=media&token=8f2d91ba-2a20-43d6-8dd9-c9aa7abf8f91

Report Date: Nov 2025

Description:

The initialization function of the StakingPool can be invoked multiple times. Repeated initialization may result in the loss of user funds.


Incorrect Return Value in Binary Search for Optimal Swap Amount

Severity: Low

Ecosystem: Sui

Protocol: Momentum CLMM

Auditor: Asymptotic

Report: https://1760493472-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FvMYfd5Y4I2ZxHbqdOD88%2Fuploads%2FVUTBtknlPDNNKXFHp9zw%2FAsymptotic Audit of Momentum CLMM.pdf?alt=media&token=e58fb859-d4be-4b65-ac1d-92df0790b6cf

Report Date: Aug 2025

Description:

The get optimal swap amount for single sided liquidity function uses a binary search to find the swap amount that best matches the optimal token ratio. While the function correctly tracks the best ratio found during the search, it does not return the swap amount corresponding to this best ratio. Instead, it returns the value calculated for the next iteration, that never runs and may not be optimal. Additionally, the binary search logic can be optimized, as it runs in a loop with some redundant assignments and unnecessarily steps. Simplifying the logic and removing redundant operations would improve both code clarity and execution efficiency.


Incorrect Validation Order: check tick range Called Before Tick Order Check

Severity: Low

Ecosystem: Sui

Protocol: Momentum CLMM

Auditor: Asymptotic

Report: https://1760493472-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FvMYfd5Y4I2ZxHbqdOD88%2Fuploads%2FVUTBtknlPDNNKXFHp9zw%2FAsymptotic Audit of Momentum CLMM.pdf?alt=media&token=e58fb859-d4be-4b65-ac1d-92df0790b6cf

Report Date: Aug 2025

Description:

In open position, check tick range is called before verify tick. However, check tick range assumes tick upper ¿ tick lower but does not check this.


Multiple Identical Pools Enable Liquidity Fragmentation

Severity: Low

Ecosystem: Sui

Protocol: Momentum CLMM

Auditor: Asymptotic

Report: https://1760493472-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FvMYfd5Y4I2ZxHbqdOD88%2Fuploads%2FVUTBtknlPDNNKXFHp9zw%2FAsymptotic Audit of Momentum CLMM.pdf?alt=media&token=e58fb859-d4be-4b65-ac1d-92df0790b6cf

Report Date: Aug 2025

Description:

The pool creation function allows multiple identical pools to be created for the same token pair, which can lead to liquidity fragmentation and user confusion. The current implementation only checks that the two token types are different (X != Y) but does not enforce canonical token ordering.


Incorrect Semantics for unblock(ALL) Operation

Severity: Low

Ecosystem: Sui

Protocol: Cetus CLMM

Auditor: Asymptotic

Report: https://drive.google.com/drive/folders/1d9nv3nJidsbQ0vDT8D1kEuR3rJzK2ULg

Report Date: Nov 2025

Description:

The restriction system treats ALL as an independent role bit rather than a composite of all operation types. When unblock(entity, ALL) is called after specific operations were blocked, those specific blocks persist. The unblock function only removes the ALL bit, leaving individual operation bits intact. However, the is blocked function correctly checks: ˆ If ALL bit is set → return blocked ˆ OR if specific operation bit is set → return blocked


Incorrect Event Emission On Multiple Liquidity Additions To Active Bin

Severity: Low

Ecosystem: Sui

Protocol: Cetus DLMM

Auditor: CertiK

Report: https://drive.google.com/drive/u/0/folders/1d9nv3nJidsbQ0vDT8D1kEuR3rJzK2ULg

Report Date: Sep 2025

Description:

The add_liquidity function calculates composition fees when a user adds liquidity to the pool's active bin. However, if a user provides the active bin's ID multiple times within a single call, a logic flaw causes the fees to be underreported in the emitted AddLiquidityEvent . The variables fee_a and fee_b , which track the fees paid, are overwritten in each loop iteration instead of being accumulated. This is possible because the function does not check to ensure the user only add liquidity to the active bin once in a call.


Add/Remove/Repay Liquidity Sequence Allows Flashloan Like Operation With No Cost

Severity: Low

Ecosystem: Sui

Protocol: Cetus DLMM

Auditor: CertiK

Report: https://drive.google.com/drive/u/0/folders/1d9nv3nJidsbQ0vDT8D1kEuR3rJzK2ULg

Report Date: Sep 2025

Description:

The add-liquidity flow mints liquidity and updates ticks immediately, returning an AddLiquidityReceipt with the owed amount_a and amount_b that must be repaid in the same transaction. No guard is preventing a user from calling remove_liquidity on the same position before calling repay_add_liquidity . This permits sourcing the repayment entirely from the pool itself within the same transaction (flashloan-like behavior), i.e., add_liquidity -> remove_liquidity -> -> repay_add_liquidity. As a result, users can effectively obtain a flashloan, even though the contract does not explicitly support flashloans, and no flashloan fee is enforced.


By Paying Swap Fees To Avoid Composition Fees From Unbalanced Liquidity During add_liquidity() And open_position()

Severity: Low

Ecosystem: Sui

Protocol: Cetus DLMM

Auditor: CertiK

Report: https://drive.google.com/drive/u/0/folders/1d9nv3nJidsbQ0vDT8D1kEuR3rJzK2ULg

Report Date: Sep 2025

Description:

Since users can utilize the already added liquidity for operations between add_liquidity() / open_position() and repay_add_liquidity() , when users need to add liquidity at an unbalanced amount_a/amount_b ratio in the active bin, they can pay swap fees through a certain method to avoid composition fees caused by unbalanced ratio.


fetch_bins() Fetches Bins From The Start Of BinGroup Instead Of The Start Bin ID

Severity: Low

Ecosystem: Sui

Protocol: Cetus DLMM

Auditor: CertiK

Report: https://drive.google.com/drive/u/0/folders/1d9nv3nJidsbQ0vDT8D1kEuR3rJzK2ULg

Report Date: Sep 2025

Description:

The previous version of fetch_bins() would return limit consecutive existing bins in the pool starting from the start bin ID. However, in the current code, since the idx in fetch_bins() is calculated starting from 0, it returns limit consecutive existing bins in the pool starting from the first bin of the BinGroup where start resides.


Discussion On reward_refunded

Severity: Low

Ecosystem: Sui

Protocol: Cetus DLMM

Auditor: CertiK

Report: https://drive.google.com/drive/u/0/folders/1d9nv3nJidsbQ0vDT8D1kEuR3rJzK2ULg

Report Date: Sep 2025

Description:

During reward_settle() , if the emergency reward pause is activated, rewards are temporarily stored in the reward_refunded variable and will only be distributed once the active bin becomes empty. However, in a well-functioning pool, the active bin becoming empty is a very rare event. If this condition does not occur for along time, the funds stored in reward_refunded will remain locked in the contract and cannot be released.


Fee Sync Blocked By Reward Permission In update_position_fee_and_rewards

Severity: Low

Ecosystem: Sui

Protocol: Cetus DLMM

Auditor: CertiK

Report: https://drive.google.com/drive/u/0/folders/1d9nv3nJidsbQ0vDT8D1kEuR3rJzK2ULg

Report Date: Sep 2025

Description:

In pool.move, update_position_fee_and_rewards ties two unrelated permissions together by calling operation_check twice, once with COLLECT_FEE and once with COLLECT_REWARD , before doing any state updates: pool.operation_check(restriction::collect_fee_kind(), ...) pool.operation_check(restriction::collect_reward_kind(), ...) operation_check asserts the corresponding pool permission flags are not disabled. As a result, update_position_fee_and_rewards will revert if either disable_collect_fee or disable_collect_reward is true, even though the function only performs internal accounting updates and does not actually transfer assets. As a result, when rewards are paused ( disable_collect_reward = true) but fee collection is allowed ( disable_collect_fee = false), LPs cannot call update_position_fee_and_rewards due to the collect_reward check, so users cannot bring their position’s fee counters up to date and will collect stale/partial fees. This creates a potential unintended denial of fee withdrawals whenever rewards are paused.


Missing Token Pair Sorting in Pool Key Generation

Severity: Low

Ecosystem: Sui

Protocol: Cetus DLMM

Auditor: MoveBit

Report: https://drive.google.com/drive/u/0/folders/1d9nv3nJidsbQ0vDT8D1kEuR3rJzK2ULg

Report Date: Sep 2025

Description:

The new_pool_key function does not sort CoinTypeA and CoinTypeB before generating the pool key, which can lead to the creation of duplicate pools for the same token pair in different orders.


Missing Validation of Current Time vs End Time in create_partner

Severity: Low

Ecosystem: Sui

Protocol: Cetus DLMM

Auditor: MoveBit

Report: https://drive.google.com/drive/u/0/folders/1d9nv3nJidsbQ0vDT8D1kEuR3rJzK2ULg

Report Date: Sep 2025

Description:

An incomplete time validation logic issue has been identified in the create_partner function within partner.move. Missing Validation: There is no check to ensure that end_time is greater than the current time. This allows the creation of a partner that has already expired at the moment of creation.


Improper Convergence Checks

Severity: Low

Ecosystem: Sui

Protocol: Aftermath

Auditor: OtterSec

Report: 

https://ottersec.notion.site/Sampled-Public-Audit-Reports-a296e98838aa4fdb8f3b192663400772

Report Date: May 2023

Description:

In the geometric_mean_calculations.move module within the following functions: calc_swap_fixed_in, calc_swap_fixed_out, calc_withdraw_fixed_amounts, and calc_deposit_fixed_amounts, the convergence between prev_t and t is checked after the while loop. However, this approach will properly execute because the t value is copied into the prev_t variable at the end of the loop.


Improper Token Weight Calculation

Severity: Low

Ecosystem: Sui

Protocol: Bucket

Auditor: OtterSec

Report: 

https://ottersec.notion.site/Sampled-Public-Audit-Reports-a296e98838aa4fdb8f3b192663400772

Report Date: June 2023

Description: get_token_weight in the tank module calculates the weight of the user’s deposit. Calculating the amount able to be withdrawn by the user uses this token weight. In this function, if the total calculated compound_stake of the user for the two scales is less than token.deposit_amount/constants::scale_factor() value, zero is returned. This results in unnecessarily reducing the user’s compounded stake.


Incorrect Key Check

Severity: Low

Ecosystem: Sui

Protocol: Scallop

Auditor: OtterSec

Report: 

https://ottersec.notion.site/Sampled-Public-Audit-Reports-a296e98838aa4fdb8f3b192663400772

Report Date: June 2023

Description:

obligation::lock is designed to lock the obligation functionality. Currently, the function invokes assert_reward_key_in_store, which is inconsistent with its intended purpose. Instead, assert_lock_key_in_store should be invoked, as the function should handle the locking of the obligation, not the rewards management.


Excessive Withdrawal Of Staked Amount

Severity: Low

Ecosystem: Sui

Protocol: Haedel LSD

Auditor: OtterSec

Report: 

https://ottersec.notion.site/Sampled-Public-Audit-Reports-a296e98838aa4fdb8f3b192663400772

Report Date: Nov 2023

Description: The issue stems from the existing implementation of get_split_amount, where a modest need_amount (e.g., 1 MIST) has the potential to trigger the withdrawal of the entire StakedSui, even if the total staked SUI amount is considerably high, instead of withdrawing only a portion of the staked amount as intended, and keeping the rest staked.


Non-Ascending Epoch Claims

Severity: Low

Ecosystem: Sui

Protocol: Haedel LSD

Auditor: OtterSec

Report: 

https://ottersec.notion.site/Sampled-Public-Audit-Reports-a296e98838aa4fdb8f3b192663400772

Report Date: Nov 2023

Description:

The issue is with regards to set_withdraw_time_limit, which grants administrators the ability to define the time limit for withdrawing staked tokens. To elaborate, should the administrator elevate the withdraw_time_limit to surpass the present timestamp calculated from the inception of the epoch, it may result in a scenario where a user generates two UnstakeTicket objects within the same epoch. In particular, if the timestamp (X) of the first ticket exceeds epoch_timestamp_ms + old_limit, and the timestamp (Y) of the second ticket falls below epoch_timestamp_ms + new_limit, the resultant EpochClaim for these two tickets will correspond to epochs E+2 and E+1, respectively. This creates a scenario where the epoch claims are in a non-ascending order, which is problematic as epoch claims should be in ascending order. This non-ascending order may disrupt the normal flow of epochbased operations.


Invalid Parameters

Severity: Low

Ecosystem: Sui

Protocol: Drife Technologies

Auditor: OtterSec

Report: 

https://ottersec.notion.site/Sampled-Public-Audit-Reports-a296e98838aa4fdb8f3b192663400772

Report Date: Dec 2023

Description: The issue is related to the fact that both stop_ride and resume_ride functions expect Driver and Rider objects to be passed as arguments at the same time. It should be impossible for the user to own both Driver and Rider objects.


Arrival Confirmation

Severity: Low

Ecosystem: Sui

Protocol: Drife Technologies

Auditor: OtterSec

Report: 

https://ottersec.notion.site/Sampled-Public-Audit-Reports-a296e98838aa4fdb8f3b192663400772

Report Date: Dec 2023

Code: N/A

Description:

In its current implementation, the system allows a driver to start a ride without confirmation from the rider that they have arrived at the pickup point. This lack of confirmation can lead to potential issues such as miscommunication or misunderstandings between the rider and the driver, affecting the system’s overall customer experience and functionality.


Improper Fee Configuration

Severity: Low

Ecosystem: Sui

Protocol: Aftermath Orderbook

Auditor: OtterSec

Report: 

https://ottersec.notion.site/Sampled-Public-Audit-Reports-a296e98838aa4fdb8f3b192663400772

Report Date: Feb 2024

Description: Fees could be negative, giving collateral to user instead of paying fees.


Rewards State Abort

Severity: Low

Ecosystem: Sui

Protocol: Suilend

Auditor: OtterSec

Report: 

https://ottersec.notion.site/Sampled-Public-Audit-Reports-a296e98838aa4fdb8f3b192663400772

Report Date: Apr 2024

Description: An edge case occurs when the length of the rewards vector in user_reward_manager is less than or equal to the current index i. This implies that there are fewer entries in the rewards vector than expected based on the iteration index. However, the if condition vector::length(&user_reward_manager.rewards) == i) only executes when the pool rewards is initialized. If the pool reward array is not contiguous, this could trigger an abort.


Ownership Transferring Not Tracked

Severity: Low

Ecosystem: Sui

Protocol: Sui Axelar(Gateway V2)

Auditor: OtterSec

Report: 

https://ottersec.notion.site/Sampled-Public-Audit-Reports-a296e98838aa4fdb8f3b192663400772

Report Date: May 2024

Description: There is an issue within process_commands in the Cross-Chain Gateway Protocol, specifically in the handling of ownership transfer calls (SELECTOR_TRANSFER_OPERATORSHIP). Currently, the function only records approved token transfer calls and does not record calls that transfer ownership. This omission opens up the possibility of relay attacks.


Potential Balance Misallocation

Severity: Low

Ecosystem: Sui

Protocol: Sui Axelar(Gateway V2)

Auditor: OtterSec

Report: 

https://ottersec.notion.site/Sampled-Public-Audit-Reports-a296e98838aa4fdb8f3b192663400772

Report Date: May 2024

Description: In get_transaction, the call to sweep is not explicitly enforced to occur after the call to swap. If the program calls SWAP_TYPE_SWEEP_DUST before SWAP_TYPE_DEEPBOOK_V2, or if there is no SWAP_TYPE_DEEPBOOK_V2 call at all, all balances of the base coin (which are supposed to be the remaining coins after the swap) will be stored in the coin_bag of the Squid router during sweep. As a result, if sweep is called before swap, all balances of coin T1 will be moved to the coin_bag of the Squid router, and neither the source nor the destination address will receive any coins. The finalize function includes a safeguard to ensure that the balance value (balance.value()) is greater than or equal to self.min_out. However, this safeguard is ineffective if min_out is set to zero.


Incorrect Whitelist Check

Severity: Low

Ecosystem: Sui

Protocol: Cetus

Auditor: OtterSec

Report: 

https://ottersec.notion.site/Sampled-Public-Audit-Reports-a296e98838aa4fdb8f3b192663400772

Report Date: May 2024

Description: config::check_token_and_min_trade_amount misuses the return value of find_token_and_min_trade_amount when require_check_token_white_list is true. The is_existed flag indicates the presence of the token in the whitelist. If it is true, the function should verify the minimum trade amount. Conversely, if is_existed is false, meaning the token is absent from the whitelist, the function should immediately return false.


Double Counting Rewards

Severity: Low

Ecosystem: Sui

Protocol: Turbos Finance

Auditor: OtterSec

Report: 

https://ottersec.notion.site/Sampled-Public-Audit-Reports-a296e98838aa4fdb8f3b192663400772

Report Date: May 2024

Description: When strategy_rewards_settle calls accumulate_rewarder_released for each rewarder, it updates the total_reward_released for the entire rewarder based on the current time and the elapsed time since the rewarder’s last_reward_time. The subsequent call to accumulate_strategy_reward also calculates elapsed time using the strategy’s last_reward_time, which may differ from the rewarder’s last_reward_time. Since accumulate_strategy_reward does not update the rewarder’s last_reward_time, the elapsed time it calculates may include a period already accounted for in the previous call to accumulate_rewarder_released. As a result, the total_reward_released for the rewarder may be incremented twice for the same elapsed period, effectively double-counting the reward.


Unhandled Proposal Removal

Severity: Low

Ecosystem: Sui

Protocol: Mysten Deepbook

Auditor: OtterSec

Report: 

https://ottersec.notion.site/Sampled-Public-Audit-Reports-a296e98838aa4fdb8f3b192663400772

Report Date: Aug 2024

Description: In governance::adjust_vote, when a proposal is removed by remove_lowest_proposal and a new proposal is subsequently created by the same account, certain issues may arise. After a proposal is removed, its ID becomes invalid in the self.proposals map. If the same account creates a new proposal, it may be assigned the same proposal_id; however, the vote count for this new proposal starts at zero.


Imbalance in LST Supply

Severity: Low

Ecosystem: Sui

Protocol: Solend Liquid Staking

Auditor: OtterSec

Report: 

https://ottersec.notion.site/Sampled-Public-Audit-Reports-a296e98838aa4fdb8f3b192663400772

Report Date: Oct 2024

Description:

Currently, create_lst_with_stake does not validate the relationship between the SUI, fungible_staked_sui, and lst_treasury_cap.total_supply values. The function only ensures that lst_treasury_cap.total_supply and the total staked SUI in the system are greater than zero.

The LST created should ideally represent a proportional claim on the underlying staked SUI assets. If there is no relationship between the total LST supply and the staked SUI, users may receive LST tokens that over- or under-represent the actual value of the staked assets. The misalignment between LST and staked SUI may result in incorrect pricing when users interact with the protocol.


Abort due to Failed Assertion Check

Severity: Low

Ecosystem: Sui

Protocol: Solend Liquid Staking

Auditor: OtterSec

Report: 

https://ottersec.notion.site/Sampled-Public-Audit-Reports-a296e98838aa4fdb8f3b192663400772

Report Date: Oct 2024

Description:

The assertion in mint within liquid_staking , while intended to maintain the balance between Liquid Staking Tokens ( LST ) and SUI, may abort under certain conditions. If old_lst_supply == 0 and old_sui_supply > 0 , the assertion will always fail. In this case, the conversion of the provided SUI amount to LST utilizing sui_amount_to_lst_amount will return the sui_amount itself.


Incorrect Price Boundary Checks

Severity: Low

Ecosystem: Sui

Protocol: Bluefin Spot

Auditor: OtterSec

Report: 

https://ottersec.notion.site/Sampled-Public-Audit-Reports-a296e98838aa4fdb8f3b192663400772

Report Date: Nov 2024

Description:

Utilizing >= and <= in the boundary checks is not appropriate, as allowing the price to hit the exact minimum or maximum boundaries will result in attempts to execute swaps that lead to invalid price states.


Incorrect Role Check

Severity: Low

Ecosystem: Sui

Protocol: Matrixdock

Auditor: Zellic

Report: https://github.com/Zellic/publications/blob/master/Matrixdock XAUm - Zellic Audit Report.pdf

Report Date: July 2025

Description: In the revoke_set_revoker function, it checks if the sender is the operator. While all functions with the revoke_ prefix are only callable by the revoker, when setting the revoker, it would be more appropriate to check if the sender is the owner. This is because the operator is only responsible for operations related to minting and burning coins.


Improper Zero Mint Check

Severity: Low

Ecosystem: Sui

Protocol: Aftermath Market Making

Auditor: OtterSec

Report: 

https://ottersec.notion.site/Sampled-Public-Audit-Reports-a296e98838aa4fdb8f3b192663400772

Report Date: Jan 2025

Description: In end_deposit_session, the check assert!(lp_to_mint != 0 only ensures that the lp_to_mint value, as calculated before the conversion to a fixed-point format ( to_balance ), is non-zero. However, the conversion process itself (specifically the call to ifixed::to_balance ) may still result in a minted amount of zero liquidity provider (LP) tokens, even if the value of lp_to_mint is non-zero prior to conversion.


Risk of Excess Recall Amount

Severity: Low

Ecosystem: Sui

Protocol: Solend Steamm

Auditor: OtterSec

Report: 

https://ottersec.notion.site/Sampled-Public-Audit-Reports-a296e98838aa4fdb8f3b192663400772

Report Date: Feb 2025

Description:

The logic in bank::recall may result in a situation where the amount_to_recall becomes greater than the available reserves due to the utilization of max(bank.min_token_block_size). The amount_to_recall is adjusted to ensure it is at least the size of bank.min_token_block_size. On recalling an amount smaller than the min_token_block_size , the function will automatically increase the recall amount to the minimum block size. The issue occurs if the available funds (the reserves in the bank) are not large enough to accommodate the adjusted amount_to_recall.


Bypassing Stake Threshold Check

Severity: Low

Ecosystem: Sui

Protocol: Mysten Walrus

Auditor: OtterSec

Report: 

https://ottersec.notion.site/Sampled-Public-Audit-Reports-a296e98838aa4fdb8f3b192663400772

Report Date: Mar 2025

Description:

ActiveSet::update does not enforce a minimum stake threshold ( set.threshold_stake ), unlike insert . This introduces a vulnerability where a user may manipulate their stake to gain a position in the active set below the required threshold.

For example, a user may stake an amount greater than set.threshold_stake, ensuring that their node is successfully inserted via ActiveSet::insert. If the active set is full, the node with the lowest stake is removed to accommodate the new entry. After successfully inserting, the user immediately calls ActiveSet::update to lower their stake below set.threshold_stake. As a result, the attacker secures a place in the active set without the required stake amount.


collect function Parameter Checking May Fail

Severity: Low

Ecosystem: Sui

Protocol: FlowX Finance

Auditor: MoveBit

Report: https://movebit.xyz/reports/FlowX-Final-Audit-Report.pdf

Report Date: May 2024

Description:

The collect function only allows the count_x_requested and count_y_requested to both be non-zero in order to pass the check_zero_amount function and if the user's position has only one token in it, he must be forced to pass one of them as an arbitrary value in order to call the collect function.


Lack of Events Emit

Severity: Low

Ecosystem: Sui

Protocol: FlowX Finance

Auditor: MoveBit

Report: https://movebit.xyz/reports/FlowX-Final-Audit-Report.pdf

Report Date: May 2024

Description:

The contract lacks appropriate events for monitoring sensitive operations, which could make it difficult to track sensitive actions or detect potential issues.


Missing Emit Event

Ecosystem: Sui

Protocol: Kuna Labs Yield Optimizer

Auditor: MoveBit

Report: https://movebit.xyz/reports/Yield-Optimizer-Final-Audit-Report.pdf

Report Date: Nov 2023

Description:

The smart contract lacks appropriate events for monitoring sensitive operations(such as managing assets and modifying key configs), which could make it difficult to track important actions or detect potential issues.


Unnecessary Parameter

Severity: Low

Ecosystem: Sui

Protocol: Cetus Farming Smart Contracts

Auditor: MoveBit

Report: https://movebit.xyz/reports/Cetus-Farming-Smart-Contract-Final-Audit-Report.pdf

Report Date: Jan 2024

Description:

In the collect_fee function, the parameters coin_a and coin_b are redundant. The return value after calling the clmm_pool::collect_fee function is the balance type, and there is no need to call the join function.


Incorrect Assert Location

Severity: Low

Ecosystem: Sui

Protocol: Cetus Farming Smart Contracts

Auditor: MoveBit

Report: https://movebit.xyz/reports/Cetus-Farming-Smart-Contract-Final-Audit-Report.pdf

Report Date: Jan 2024

Description:

Assert of the reward_balance and amount quantities are ineffective when placed after the split function, they should be placed before.


set_prize_rate Should Check If It Is New Rate

Severity: Low

Ecosystem: Sui

Protocol: Random-Vault

Auditor: MoveBit

Report: https://movebit.xyz/reports/Random-Vault-Final-Audit-Report.pdf

Report Date: Feb 2024

Description:

In config.move , there should be assertion to check that in set_prize_rate function, config.prize_rates != rates .


queryWinRate Does Not Handle User Withdrawed

Severity: Low

Ecosystem: Sui

Protocol: Random-Vault

Auditor: MoveBit

Report: https://movebit.xyz/reports/Random-Vault-Final-Audit-Report.pdf

Report Date: Feb 2024

Description:

In the design of the lottery.move once a user withdraws any amount in a round, he will not be able to participate in the lottery, which means he has a win rate of 0. However, the queryWinRate function, does not handle such a case but directly computes the win rate using its share. This will lead to confusion of the user and a poor user experience.


Possible Zero Token Minted in mint_market_coin Function

Severity: Low

Ecosystem: Sui

Protocol: Scallop

Auditor: MoveBit

Report: https://github.com/movebit/Sampled-Audit-Reports/blob/main/reports/Scallop-Smart-Contract-Audit-Report.pdf

Report Date: June 2023

Description:

If balance_sheet.cash + balance_sheet.debt is greater than balance_sheet.market _coin_supply and underlying_amount is relatively small, resulting in a mint_amount of 0. This can lead to a situation where the user deposits funds (underlying_balance), but no MarketCoin shares are minted, resulting in the user not receiving any shares for their deposit.


Suggest Throw abort Instead Of Returning false

Severity: Low

Ecosystem: Sui

Protocol: Legend of Arcadia

Auditor: MoveBit

Report: https://github.com/movebit/Sampled-Audit-Reports/blob/main/reports/Legend-of-Arcadia-Smart-Contract-Audit-Report.pdf

Report Date: June 2023

Description:

Among the multiple execute functions of the arca module, When the Proposal is not marked complete, it is recommended not to return false, but throw an exception abort at the end of the function, and no transaction will be generated.


get_auction_max_size Missing Check

Severity: Low

Ecosystem: Sui

Protocol: Typus Finance

Auditor: MoveBit

Report: https://github.com/movebit/Sampled-Audit-Reports/blob/main/reports/Typus-Finance-Smart-Contract-Audit-Report.pdf

Report Date: May 2023

Description:

In get_auction_max_size, there is no assertion added to the return value of calculate_max_loss_per_unit, assert!(i64::is_neg(&max_loss), E_INVALID_MAX_LOSS); other calls to calculate_max_loss_per_unit are added.


The Method for Obtaining coin_decimals is Incorrect

Severity: Low

Ecosystem: Sui

Protocol: Navi

Auditor: MoveBit

Report: https://github.com/movebit/Sampled-Audit-Reports/blob/main/reports/Navi-Smart-Contract-Audit-Report.pdf

Report Date: July 2023

Description:

In the init_reserve() function, coin_decimals should not be passed in as a parameter, but should be obtained through the CoinType.


Redundant assert Statements

Severity: Low

Ecosystem: Sui

Protocol: KriyaDEX

Auditor: MoveBit

Report: https://github.com/movebit/Sampled-Audit-Reports/blob/main/reports/KriyaDEX-Smart-Contract-Audit-Report.pdf

Report Date: May 2023

Description:

The assert validation always passes when adding liquidity because its condition is the same as the previous if statement.


The Condition of the Assert is Incorrect

Severity: Low

Ecosystem: Sui

Protocol: KriyaDEX

Auditor: MoveBit

Report: https://github.com/movebit/Sampled-Audit-Reports/blob/main/reports/KriyaDEX-Smart-Contract-Audit-Report.pdf

Report Date: May 2023

Description:

In the function swap_token_y(), the validation should be for amount > 0 instead of token_y_balance > 0. The same issue also exists in lines 315 and 466.


change_order Function Design Flaw

Severity: Low

Ecosystem: Sui

Protocol: MovEX

Auditor: MoveBit

Report: https://github.com/movebit/Sampled-Audit-Reports/blob/main/reports/MovEx-Smart-Contract-Audit-Report.pdf

Report Date: May 2023

Description:

In the change_order function, if the TypeName of the two tokens to be processed is the same, an empty array will be pop_backed and an error will be reported. At the same time, an error will be reported when the TypeName of the two tokens is the same but the length is not equal.


K Value Check Condition Error

Severity: Low

Ecosystem: Sui

Protocol: MovEX

Auditor: MoveBit

Report: https://github.com/movebit/Sampled-Audit-Reports/blob/main/reports/MovEx-Smart-Contract-Audit-Report.pdf

Report Date: May 2023

Description:

At the end of the swap function, the value of k in the pool will be limited to an increase, but this is for the case of handling fees. When fee_percent is set to 0, swap will not change the value of k in the pool, so when the limit k is increased, the handling fee Pools with a value of 0 cannot be swapped normally, and the condition of liquidity_before_swap < liquidity_after_swap should be changed to <=.


Function Logic Does Not Match the Annotation

Severity: Low

Ecosystem: Sui

Protocol: Aries Market (Sui)

Auditor: MoveBit

Report: https://github.com/movebit/Sampled-Audit-Reports/blob/main/reports/Aries-Smart-Contract-Audit-Report.pdf

Report Date: June 2023

Description:

When allow_collateral and allow_redeem are set to false, the value of the user's collateral is 0, which will prevent the user from withdrawing, borrowing, etc., and the comment means whether to allow the use of collateral to continue borrowing, and there is a conflict between the two.


Unchecked Return

Severity: Low

Ecosystem: Sui

Protocol: Aries Market (Sui)

Auditor: MoveBit

Report: https://github.com/movebit/Sampled-Audit-Reports/blob/main/reports/Aries-Smart-Contract-Audit-Report.pdf

Report Date: June 2023

Description:

Certain library functions such as coin::burn(), vec_map::remove(), table::remove(), bag::remove(), balance::join(), and balance::decrease_supply() have return values, but are not being properly utilized in the code. Similarly, functions such as market::init_market(), profile::add_profile(), market::add_reserve(), lending::deposit_with_repay(), reserve::repay(), and reserve::deposit_lp_co in() also have return values but are not being properly utilized when called. This could result in important return values not being checked, potentially leading to security vulnerabilities.


Incorrect Event Timestamp Parameter Setting

Severity: Low

Ecosystem: Sui

Protocol: Aries Market (Sui)

Auditor: MoveBit

Report: https://github.com/movebit/Sampled-Audit-Reports/blob/main/reports/Aries-Smart-Contract-Audit-Report.pdf

Report Date: June 2023

Description:

It was identified that within the reserve_status::emit_record_status() function, the record_timestamp parameter was constantly set to 0 when emitting an event.


Logic Repetition

Severity: Low

Ecosystem: Sui

Protocol: Cetus Concentrated Liquidity Protocol (Sui)

Auditor: MoveBit

Report: https://github.com/movebit/Sampled-Audit-Reports/blob/main/reports/Cetus-Concentrated-Liquidity-Protocol-Sui-Contract-Audit-Report.pdf

Report Date: Apr 2023

Description:

The verification logic for positive and negative numbers in the function cmp is consistent.


Abort on Temporary Imbalance During Epoch Transition

Severity: Low

Ecosystem: Aptos

Protocol: Kofi Finance Contacts

Auditor: OtterSec

Report: https://ottersec.notion.site/Sampled-Public-Audit-Reports-a296e98838aa4fdb8f3b192663400772

Report Date: May 2025

Description:

A strict assertion in update_rewards causes staking operations to fail during temporary imbalances between total kAPT and total staked APT.


Unnecessary Assertion Causes Protocol Lockup

Severity: Low

Ecosystem: Aptos

Protocol: Kofi Finance Contacts

Auditor: OtterSec

Report: https://ottersec.notion.site/Sampled-Public-Audit-Reports-a296e98838aa4fdb8f3b192663400772

Report Date: May 2025

Description:

The ratio <= RATIO_MAX assertion in math::ratio can permanently lock protocol liquidity if the ratio naturally grows beyond the limit.


Protocol Insolvency via Validator Removal

Severity: Low

Ecosystem: Aptos

Protocol: Kofi Finance Contacts

Auditor: OtterSec

Report: https://ottersec.notion.site/Sampled-Public-Audit-Reports-a296e98838aa4fdb8f3b192663400772

Report Date: May 2025

Description:

Removing validators may result in irretrievable stake, risking temporary protocol insolvency.


Buffer Vault Drainage Due to Unaccounted Staking Fees

Severity: Low

Ecosystem: Aptos

Protocol: Kofi Finance Contacts

Auditor: OtterSec

Report: https://ottersec.notion.site/Sampled-Public-Audit-Reports-a296e98838aa4fdb8f3b192663400772

Report Date: May 2025

Description:

Unaccounted staking fees during delegation cause the buffer vault to burn more than it mints, gradually depleting its balance and risking protocol stability.


Faulty Withdrawal Logic

Severity: Low

Ecosystem: Aptos

Protocol: Kofi Finance Contacts

Auditor: OtterSec

Report: https://ottersec.notion.site/Sampled-Public-Audit-Reports-a296e98838aa4fdb8f3b192663400772

Report Date: May 2025

Description:

delegation_manager::withdraw_stake assumes that withdrawn_amount is always greater than the minimum threshold, risking unexpected aborts if this condition is not met.


Flaw in Reward Withdrawal Logic

Severity: Low

Ecosystem: Aptos

Protocol: Echleon

Auditor: OtterSec

Report: https://ottersec.notion.site/Sampled-Public-Audit-Reports-a296e98838aa4fdb8f3b192663400772

Report Date: Apr 2025

Description:

claim_reward_fa incorrectly utilizes fungible_asset::withdraw, preventing reward claims if the reward FA is dispatchable.


Premature Reward Claiming

Severity: Low

Ecosystem: Aptos

Protocol: Merkle Token

Auditor: OtterSec

Report: https://ottersec.notion.site/Sampled-Public-Audit-Reports-a296e98838aa4fdb8f3b192663400772

Report Date: July 2024

Description:

The vulnerability in claim_rewards arises from the fact that protocol rewards may be claimed for future epochs or even the current epoch. This is problematic because the rewards for these epochs, as well as the stake distribution, are not yet finalized. Since the total rewards and individual stakes are not finalized for future and current epochs, any claim made during these times may be based on incomplete or inaccurate data. Users may receive more or less than their fair share, resulting in an unfair distribution of rewards.


Permanent Loss Of Expired Rewards

Severity: Low

Ecosystem: Aptos

Protocol: Merkle Token

Auditor: OtterSec

Report: https://ottersec.notion.site/Sampled-Public-Audit-Reports-a296e98838aa4fdb8f3b192663400772

Report Date: July 2024

Description:

Currently, if rewards are not claimed within a 14-day period, they become inaccessible and may not be retrieved or re-utilized. claim_rewards contains a check that ensures rewards may only be claimed if they are within a 14-day window from their registration. If this period expires, the reward claim fails with the E_CLAIM_EXPIRED error. This rule is meant to ensure that rewards are claimed in a timely manner.

Improper Reward Distribution

Severity: Low

Ecosystem: Aptos

Protocol: TruFin

Auditor: OtterSec

Report: https://ottersec.notion.site/Sampled-Public-Audit-Reports-a296e98838aa4fdb8f3b192663400772

Report Date: May 2024

Description:

The delegation_pool transfers the add_stake_fees to the NULL_SHAREHOLDER and later returns them to the pool at the end of the epoch. This process occurs because the delegation pool does not distinguish between active and pending_active users, allowing both groups to receive rewards. To ensure active users get their rewards and pending_active users receive their add_stake_fees as rewards in the subsequent epoch, the system imposes add_stake_fees on users. In this protocol, add_stake_fees, which are distributed as rewards in the next epoch, are treated as stake within the same epoch, resulting in the minting of TruAPT. Consequently, users will receive extra rewards from others who are active in the subsequent epoch.


Inappropriate Unlock Amount

Severity: Low

Ecosystem: Aptos

Protocol: TruFin

Auditor: OtterSec

Report: https://ottersec.notion.site/Sampled-Public-Audit-Reports-a296e98838aa4fdb8f3b192663400772

Report Date: May 2024

Description:

internal_unlock unlocks the amount from the delegation pool and burns the equivalent TruAPT tokens. It creates an UnlockRequest for the user with the unstaked amount, which later facilitates the withdrawal of APT from the protocol. unstaked_apt represents the actual stake amount being unstaked from the delegation pool. Additionally, amount sometimes exceeds the unstaked amount, potentially disbursing more APT than intended. Therefore, it is advisable to utilize unstaked_apt to create the unlock request.


Improper Implementation Of Withdraw All

Severity: Low

Ecosystem: Aptos

Protocol: Thala Labs

Auditor: OtterSec

Report: https://ottersec.notion.site/Sampled-Public-Audit-Reports-a296e98838aa4fdb8f3b192663400772

Report Date: May 2023

Description:

A pool creator has the option to remove liquidity from the pool by specifying a percentage of liquidity to be removed in bps format. However, if the LBP is still ongoing, only a portion of the liquidity can be removed from the pool, with the entire liquidity only being removable once the LBP has concluded. This is implemented through a check of the remove_bps variable to see if it is equal to BPS_BASE. If this check evaluates as true, an assertion is made to ensure that the LBP has indeed ended before allowing for complete liquidity removal. This can be easily bypassed by passing in remove_bps = 9999 and calling the remove_liquidity multiple times. This removes all the liquidity from the pool even when the LBP has not ended.


Incorrect Variable

Severity: Low

Ecosystem: Aptos

Protocol: Steamflow

Auditor: OtterSec

Report: https://ottersec.notion.site/Sampled-Public-Audit-Reports-a296e98838aa4fdb8f3b192663400772

Report Date: Mar 2023

Description:

In protocol::create, validate_contract_params is utilized to validate the input parameters that are related to amounts. However, the calculate_end, which is responsible for calculating the end-time value used in validate_contract_params, is currently receiving the amount value rather than the amount_per_period value. As a result, calculate_end always returns the end-time value for only one period, which could potentially bypass the end < start + SEVENTY_YEARS_IN_SECS check in validate_contract_params.


Improper Path Validation And Usage

Severity: Low

Ecosystem: Aptos

Protocol: Eternal Finance

Auditor: OtterSec

Report: https://ottersec.notion.site/Sampled-Public-Audit-Reports-a296e98838aa4fdb8f3b192663400772

Report Date: Jan 2023

Description:

In pancake_dex_helper.move, the set_paths function sets a path to be used when reinvesting Cake rewards, verifying whether the path exists or not. When idx = 2, the function checks whether the path Cake -> AptosCoin -> X exists or not. However, in the get_lp_by_cake function, when path = 2, it uses the Cake -> AptosCoin -> Y path to convert the Cake rewards to Y token, which is inconsistent with the validations in the set_paths function. This inconsistency could potentially cause the get_lp_by_cake function to fail. When path = 2, the function attempts to convert Cake rewards from Cake -> AptosCoin -> Y, but this path may not exist.


Faulty Token Struct Comparison

Severity: Low

Ecosystem: Aptos

Protocol: Pancake Swap

Auditor: OtterSec

Report: https://ottersec.notion.site/Sampled-Public-Audit-Reports-a296e98838aa4fdb8f3b192663400772

Report Date: Nov 2022

Description:

In order to construct a deterministic ordering of two tokens in a swap pair, it is necessary to be able to compare them. The current implementation concatenates the address, module, and struct names into a vector and invokes compare_u8_vector. This implementation generates collisions for certain token structs that should not collide. For example, the following two structs would generate the same comparison string. Both structs generate the string: addressFOOBAR. The protocol will incorrectly reject this swap pair from being constructed.


SplayTree Inoperable Remove Functions

Severity: Low

Ecosystem: Aptos

Protocol: Laminar Markets

Auditor: OtterSec

Report: https://ottersec.notion.site/Sampled-Public-Audit-Reports-a296e98838aa4fdb8f3b192663400772

Report Date: Oct 2022

Description:

Functions remove_nodes_greater_than and remove_nodes_less_than don’t work if provided with values greater than the max node and lesser than the min node respectively. When the given scenario is met, the deletion of nodes will not occur.


Ensure Contract Upgrade Integrity

Severity: Low

Ecosystem: Aptos

Protocol: Wormhole Aptos

Auditor: OtterSec

Report: https://ottersec.notion.site/Sampled-Public-Audit-Reports-a296e98838aa4fdb8f3b192663400772

Report Date: Oct 2022

Description:

In both wormhole and token-bridge, contract upgrade via governance is a two step process:

  1. A user invokescontract_upgrade::submit_vaawith a governance VAA that includes ahash of the intended upgrade code.
  2. A user invokescontract_upgrade::upgradewith the actualmodule code which subsequently invokes code::publish_package_txn to upgrade the contract. Both of these calls are permissionless (can be invoked by any user). Integrity is protected in the first call by verifying the guardian signatures on the VAA. Integrity is protected in the second call by ensuring the provided module code matches the hash. However, in the original implementation, we identified two issues that would allow an attacker to provide alternative module code that still matches the stored hash:

Serialized Metadata A module upgrade package contains a list of code modules (vector<vector>) and serialized metadata (vector). In the original implementation, metadata_serialized was not included in the hash. Therefore, an attacker could provide any arbitrary metadata that would not cause the deployment to abort.

Module Boundaries The original hash was computed by first concatenating the code modules and then taking the hash of the concatenated structure. However, this implementation does not properly validate module code boundaries. Specifically, moving N bytes of code from the end of one module to the start of another would not affect the hash:

It is unclear whether an attacker could exploit this collision to deploy a malformed version of the module. However, since the fix is simple, it is preferable to reduce the attack surface as much as possible.


The Necessity of Controlling Return Value Order in the token_reserves() Function

Severity: Low

Ecosystem: Aptos

Protocol: Baptswap

Auditor: MoveBit

Report: https://movebit.xyz/reports/BAPTSWAP-Final-Audit-Report.pdf

Report Date: Dec 2023

Description:

The function token_reserves() adjusts the order of returned values by sorting currencies, which might not be necessary. As the order has already been adjusted before calling this function within the current contract, the if statement is executed every time. To prevent confusion, we believe that the control over the sequence should occur when receiving the return values of this function, rather than within the current function. We also compared this to PancakeSwap's code, which similarly does not control the sequence within the current function.


tp_percent Should Be Less Than or Equal to pair_info.maximum_profit

Severity: Low

Ecosystem: Aptos

Protocol: Merkle Trade Smart Contract

Auditor: MoveBit

Report: https://movebit.xyz/reports/Merkle-Trade-Smart-Contract-Audit-Report.pdf

Report Date: July 2023

Description:

The function execute_increase_order_internal() is responsible for executing an increase order in a trading pair. Inside the function, the stop-loss and take-profit prices of the position are updated based on the order's type and the specified conditions. If the order's take-profit trigger price and the maximum take-profit price are the same, the code will assign that value to the take-profit trigger price of the position. In other words, there is no preference for either value in this scenario, and they are considered equal. However, inside the update_position_tp_sl() , an assertion is made to validate that the calculated take-profit percentage is less than the maximum allowed profit percentage specified in the pair's information. The business logic of this function, update_position_tp_sl() , is different from execute_increase_order_internal() .


Vault Amount Checks Are Not Implemented In Every Operation

Severity: Low

Ecosystem: Aptos

Protocol: Superposition

Auditor: MoveBit

Report: https://movebit.xyz/reports/Superposition-Final-Audit-Report.pdf

Report Date: Mar 2024

Description:

In super postion , the user can perform different operations such as borrow, redeem, repay . And each operation will affect the vault amount differently. However, some operations (repay, redeem) don't have vault checks before and after the operation. And the pre-vault amount calculations are not the same for the other. This would lower the security of the vault and cause misalignment in design.


The verification conditions of assert and if are repeated

Severity: Low

Ecosystem: Aptos

Protocol: Mokshya/Wapal Aptos NFT Mint Smart Contract

Auditor: MoveBit

Report: https://github.com/movebit/Sampled-Audit-Reports/blob/main/reports/Mokshya-Wapal-Aptos-NFT-Mint-Smart-Contract-Audit.pdf

Report Date: Mar 2023

Description:

In the function candymachine::mint_from_merkle, use assert to verify that is_whitelist_mint is true to continue to execute the code, and then repeat the judgment through if. In the function candymachine::update_candy , assert has been used to verify that publ ic_sale_mint_time >= now && presale_mint_time >= now, and the judgment is repeated through if below.


The assert judgment condition is inaccurate

Severity: Low

Ecosystem: Aptos

Protocol: Aries Market(Aptos)

Auditor: MoveBit

Report: https://github.com/movebit/Sampled-Audit-Reports/blob/main/reports/Aries-Market-Contracts-Audit-Report.pdf

Report Date: Feb 2023

Description:

In the function validate_oracle_info , when sb_weight=0 , pyth_weight=U64_MAX , or sb_weight=U64_MAX , pyth_weight=0 , the assertion condition is not met, causing oracle verification to fail.


Inaccurate judgment on deposit and loan restrictions

Severity: Low

Ecosystem: Aptos

Protocol: Aries Market(Aptos)

Auditor: MoveBit

Report: https://github.com/movebit/Sampled-Audit-Reports/blob/main/reports/Aries-Market-Contracts-Audit-Report.pdf

Report Date: Feb 2023

Description:

In the following functions, when determining whether the deposit and loan amount exceeds the limit, the numerical comparison is inaccurate, and the numerical value should be less than or equal to the limit, not less than.


Incorrect check for minimum order size

Severity: Low

Ecosystem: Aptos

Protocol: Econia

Auditor: Zellic

Report: https://github.com/Zellic/publications/blob/master/Econia - Zellic Audit Report.pdf

Report Date: Jan 2023

Description:

After performing the order book match to attempt to fill a new limit order, the place_limit_order function returns early without placing an order for the remaining unfilled size only if the order is of type IMMEDIATE_OR_CANCEL or if the remaining order size is zero. This is incorrect, as the remaining order size can be lower than the minimum order size configured for the market.


The sendOFT function call can be blocked

Severity: Low

Ecosystem: Aptos

Protocol: Layer Zero OFT Wrapper

Auditor: Zellic

Report: https://github.com/Zellic/publications/blob/master/LayerZero OFT Wrapper Audit (January 19th 2023) - Zellic Audit Report.pdf

Report Date: Nov 2022

Description:

The contract owner can set any bps value of the variables defaultBps and the oftBps [_oft] in the range from 0 to the maximum BPS_DENOMINATOR inclusive. But during the sendOFT function call, the getAmountAndFees function will check that the final bps value is less than BPS_DENOMINATOR and revert the transaction if it equals or more.


Missing assertion checks for critical protocol parameters

Severity: Low

Ecosystem: Aptos

Protocol: Aptos Dollar

Auditor: Zellic

Report: https://github.com/Zellic/publications/blob/master/Thala Labs Move Dollar - Zellic Audit Report.pdf

Report Date: Oct 2022

Description:

There are no checks in place to enforce that params::set_params has been called for a given CoinType prior to calling vault::initialize.


The ascending insertion search fails to return the tail

Severity: Low

Ecosystem: Aptos

Protocol: Aptos Dollar

Auditor: Zellic

Report: https://github.com/Zellic/publications/blob/master/Thala Labs Move Dollar - Zellic Audit Report.pdf

Report Date: Oct 2022

Description:

The sorted_vaults::find_insert_position_ascending search algorithm fails to return the tail position.


Instances of none in VaultStore.vault

Severity: Low

Ecosystem: Aptos

Protocol: Aptos Dollar

Auditor: Zellic

Report: https://github.com/Zellic/publications/blob/master/Thala Labs Move Dollar - Zellic Audit Report.pdf

Report Date: Oct 2022

Description:

Calls to vault::close_vault leave the vault store with a none vault.


Emode LTV & LT invariants can be broken

Severity: Low

Ecosystem: Aptos

Protocol: AAVE v3.0.2 Core

Auditor: Spearbit

Report: https://github.com/aave/aptos-aave-v3/blob/main/audits/Spearbit%20Aave%20Aptos%20Core%20V3.0.2%20Report.pdf

Report Date: Jun 2025

Description:

Entering an emode category as a user should never be worse for the user's health. Therefore, functions like pool_configurator::set_emode_category check that the following reserve <>emode[reserve.emodeCategroy] invariant holds.

However, this invariant does not hold because not all functions that can change the reserve's / emode's LTV/LT enforce it.


set_user_emode health check always needs to be performed

Severity: Low

Ecosystem: Aptos

Protocol: AAVE v3.0.2 Core

Auditor: Spearbit

Report: https://github.com/aave/aptos-aave-v3/blob/main/audits/Spearbit%20Aave%20Aptos%20Core%20V3.0.2%20Report.pdf

Report Date: Jun 2025

Description:

The emode_logic::set_user_emode function skips the health check when the user goes from noemode to new emode.

The idea is likely that if the following invariants hold, the health can only increase, and therefore set_user_emode cannot be used to turn a healthy user into an unhealthy user.

However, this invariant does not hold because of the finding "Emode LTV & LT invariants can be broken". The impact is that a healthy user can call set_user_emode and end up unhealthy after the call. This is bad for the user as they can be liquidated afterwards. In addition, having a programmatic way for turning any position liquidatable (under the right circumstances) in a single transaction poses security risks (f.i., see the Euler Finance hack analysis by Cyfrin) and protocol bad debt risk.


token_base events do not identify the token used

Severity: Low

Ecosystem: Aptos

Protocol: AAVE v3.0.2 Core

Auditor: Spearbit

Report: https://github.com/aave/aptos-aave-v3/blob/main/audits/Spearbit%20Aave%20Aptos%20Core%20V3.0.2%20Report.pdf

Report Date: Jun 2025

Description:

The token_base module is used by all aTokens and vTokens to perform the base token actions like transfers. The emitted Transfer, Mint, Burn events do not identify the actual tokens these events were emitted for. The events are currently not useful for data processing because one can't identify if the Transfer was for aUSDC, aAPT, etc


init_reserves does not support yet the deployment of a reserve with preconfigured incentives_controllers

Severity: Low

Ecosystem: Aptos

Protocol: AAVE v3.0.2 Core

Auditor: Spearbit

Report: https://github.com/aave/aptos-aave-v3/blob/main/audits/Spearbit%20Aave%20Aptos%20Core%20V3.0.2%20Report.pdf

Report Date: Jun 2025

Description:

The current implementation of pool_configurator::init_reserves does not include the input parameter incentives_controllers which is passed "empty" (option::none()) to the pool_token_logic::init_reserve. This means that every reserve will always be initialized with an empty incentive controller that needs to be configured later on.


"Same" events are defined multiple times across modules

Severity: Low

Ecosystem: Aptos

Protocol: AAVE v3.0.2 Core

Auditor: Spearbit

Report: https://github.com/aave/aptos-aave-v3/blob/main/audits/Spearbit%20Aave%20Aptos%20Core%20V3.0.2%20Report.pdf

Report Date: Jun 2025

Description:

In Aptos, events with the same names and struct fields that are defined in separate modules will be treated as separate events. This makes it hard to query for the event as the event needs to be queried across all modules it is defined in and the results must be merged. The proper approach is to have the event defined in a single module. Some events that represent a single event in Aave Solidity are defined across several modules in Aave Move.


token_base allows A/V token to de-sync the incentive controllers

Severity: Low

Ecosystem: Aptos

Protocol: AAVE v3.0.2 Core

Auditor: Spearbit

Report: https://github.com/aave/aptos-aave-v3/blob/main/audits/Spearbit%20Aave%20Aptos%20Core%20V3.0.2%20Report.pdf

Report Date: Jun 2025

Description:

When the reserve is deployed, the caller provides only one common (empty or not) incentive controller to be used for both the AToken and VariableDebtToken. The set_incentives_controller allows the caller to set a new (empty or not) incentives_controller for the single AToken or VariableDebtToken. This behavior allows the system to de-sync the tokens incentive controller that should be the same given the assumption used during the reserve's initialization. With the current logic, we could end up with: • A/V tokens are configured with different incentive controllers. • One of the two token have the incentive controller configured and the other not.


Side effects of deploying the AToken and VariableDebtToken as FungibleAsset

Severity: Low

Ecosystem: Aptos

Protocol: AAVE v3.0.2 Core

Auditor: Spearbit

Report: https://github.com/aave/aptos-aave-v3/blob/main/audits/Spearbit%20Aave%20Aptos%20Core%20V3.0.2%20Report.pdf

Report Date: Jun 2025

Description:

In the current implementation of the Aptos codebase both the AToken and VariableDebtToken are deployed as FungibleAsset. When the user mint AToken or VariableDebtToken, the receiving wallet is immediately frozen (see token_base.move?lines=260,265).


Updating/Fetching the reward's emission admin should not revert when there's no rewards_controller configured

Severity: Low

Ecosystem: Aptos

Protocol: AAVE v3.0.2 Periphery

Auditor: Spearbit

Report:

https://github.com/aave/aptos-aave-v3/blob/main/audits/Spearbit Aave Aptos Periphery V3.0.2 Report.pdf

Report Date: Jun 2025

Description:

The rewards_controller attribute stored in the EmissionManagerData struct of the emission_- manager holds the value of the "current" rewards_controller configured. Such value could be not configured yet or simply set to option::none() to state the that there's no not a current reward controller in action. The emission admin of a reward is stored as an item of emission_admins: SmartTable<address, address> in the EmissionManagerData struct is not bound to the value of rewards_controller. The @aave_pool admin user should always be able to configure/update an emission admin for a reward, even if the rewards_controller has not been configured yet. The same should also be true for the getter function relative to the reward's emission admin.


rewards_controller module events are not tracking which rewards_controller_address has emitted them

Severity: Low

Ecosystem: Aptos

Protocol: AAVE v3.0.2 Periphery

Auditor: Spearbit

Report:

https://github.com/aave/aptos-aave-v3/blob/main/audits/Spearbit Aave Aptos Periphery V3.0.2 Report.pdf

Report Date: Jun 2025

Description:

The rewards_controller module can be seen as a "factory" of rewards controllers. Almost all the functions take an arbitrary rewards_controller_address address as an input parameter to distinguish which reward controller is being used for the internal function logic.


Aave Core and Aave Reward use the same oracle's module

Severity: Low

Ecosystem: Aptos

Protocol: AAVE v3.0.2 Periphery

Auditor: Spearbit

Report:

https://github.com/aave/aptos-aave-v3/blob/main/audits/Spearbit Aave Aptos Periphery V3.0.2 Report.pdf

Report Date: Jun 2025

Description:

With the current implementation of the Aptos codebase, the oracle module maps both the prices of the assets used as Aave Protocol Core reserves and the one used as rewards of the Aave Periphery reward system.


rewards_controller::handle_action should never revert

Severity: Low

Ecosystem: Aptos

Protocol: AAVE v3.0.2 Periphery

Auditor: Spearbit

Report:

https://github.com/aave/aptos-aave-v3/blob/main/audits/Spearbit Aave Aptos Periphery V3.0.2 Report.pdf

Report Date: Jun 2025

Description:

The handle_action function of the rewards_controller modules is called by the AToken or VariableDebtToken logic when the user mint/burn/transfer those tokens. Reverting during the execution of the handle_action function means that the above functions (in the AToken or VariableDebtToken context), that are crucial in the Aave Core logic, would break. If the incentives_controller attribute has not been configured (empty) or is misconfigured, the handle_action should just return early without tracking the user rewards and never revert.


Users near MIN_BASE_MAX_CLOSE_FACTOR_THRESHOLD can be fully liquidated by using multi liquidations

Severity: Low

Ecosystem: Aptos

Protocol: AAVE v3.1-3.3 Core

Auditor: Spearbit

Report: https://github.com/aave/aptos-aave-v3/blob/main/audits/Spearbit Aave Aptos Core V3.1-V3.3 Report.pdf

Report Date: Jun 2025

Description:

Aave 3.3 introduced new minimum position size thresholds that must exist after liquidations if the entire balance cannot be cleared. This is to prevent position sizes of small amounts that are not unprofitable to liquidate, for example, because of gas costs. • The MIN_BASE_MAX_CLOSE_FACTOR_THRESHOLD is currently set to 2000$. • The "dust value" is half of that, set to MIN_LEFTOVER_BASE = 1000$. The rules are as follows: • Full-liquidation: The max close factor is 50% of the user's total debt value (no full liquidation) if-and-only-if HF > 95% AND debt$ >= 2000$ AND collateral$ >= 2000$. Otherwise, the close factor is 100%. • Liquidation failures due to dust position sizes: Liquidation fails if both collateral and debt balances are non-zero after the liquidation and any of the balances is less than 1000$: collateral_left$ > 0 AND debt_left$ > 0 AND (collateral_left$ < 1000$ OR debt_left$ < 1000$).


Minimum position size post-liquidation checks can end up reverting legitimate liquidations

Severity: Low

Ecosystem: Aptos

Protocol: AAVE v3.1-3.3 Core

Auditor: Spearbit

Report: https://github.com/aave/aptos-aave-v3/blob/main/audits/Spearbit Aave Aptos Core V3.1-V3.3 Report.pdf

Report Date: Jun 2025

Description:

Aave 3.3 introduced new minimum position size thresholds that must exist after liquidations if the entire balance cannot be cleared. This is to prevent position sizes of small amounts that are not unprofitable to liquidate, for example, because of gas costs. • The MIN_BASE_MAX_CLOSE_FACTOR_THRESHOLD is currently set to 2000$. • The "dust value" is half of that, set to MIN_LEFTOVER_BASE = 1000$. The rules are as follows: • Full-liquidation: The max close factor is 50% of the user's total debt value (no full liquidation) if-and-only-if HF > 95% AND debt$ >= 2000$ AND collateral$ >= 2000$. Otherwise, the close factor is 100%. • Liquidation failures due to dust position sizes: Liquidation fails if both collateral and debt balances are non-zero after the liquidation and any of the balances is less than 1000$: collateral_left$ > 0 AND debt_left$ > 0 AND (collateral_left$ < 1000$ OR debt_left$ < 1000$).


AggregatedReserveData misses the virtual_underlying_balance and is_virtual_acc_active data attributes

Severity: Low

Ecosystem: Aptos

Protocol: AAVE v3.1-3.3 Core

Auditor: Spearbit

Report: https://github.com/aave/aptos-aave-v3/blob/main/audits/Spearbit Aave Aptos Core V3.1-V3.3 Report.pdf

Report Date: Jun 2025

Description:

The AggregatedReserveData struct in ui_pool_data_provider_v3 is missing two attributes that should be returned by the get_reserves_data function. These two values are: • virtual_underlying_balance which represents the underlying balance held in the AToken resource account. • is_virtual_acc_active reserve flag


Improper Event Emission Due to Variable Shadowing

Severity: Low

Ecosystem: Aptos

Protocol: AAVE v3.0.2 Core

Auditor: Certora

Report: https://github.com/aave/aptos-aave-v3/blob/main/audits/Ottersec Aave Aptos V3.1-V3.3 Report.pdf

Report Date: Apr 2025

Description:

The pending_ltv_set variable is shadowed inside the if block, resulting in the emitted event always reporting a zero value instead of the actual LTV .


Hardcoded Dust Threshold in Swap Logic

Severity: Low

Ecosystem: Aptos

Protocol: Hyperionxyz Vaults

Auditor: ExVul

Report: https://github.com/ExVul-Sec/AuditReport/blob/main/Smartcontract/Hyperion Smart Contrat Audit Report-Exvul.pdf

Report Date: Apr 2025

Description:

The threshold 10 used to decide whether to perform another swap (swap_deposit) is hardcoded. This doesn't account for the varying decimal places of different tokens, potentially leaving significant value as dust for some tokens or unnecessarily swapping for others.


Bypassing team_reward Limitation

Severity: Low

Ecosystem: Aptos

Protocol: TokimonsterAI

Auditor: ExVul

Report: https://github.com/ExVul-Sec/AuditReport/blob/main/Smartcontract/TokimonsterAI Smarat Contract Audit Report-Exvul.pdf

Report Date: May 2025

Description:

In the initialize function of TokimonsterRewarder, there is a constraint ensuring team_reward does not exceed 100. However, the set_override_team_rewards_for_token and add_user_reward_recipient functions lack similar limitations. If team_reward is set above 100, extract operations will fail due to insufficient funds, creating a potential vulnerability.


Invalid Address Replacement in replace_user_reward_recipient Function

Severity: Low

Ecosystem: Aptos

Protocol: TokimonsterAI

Auditor: ExVul

Report: https://github.com/ExVul-Sec/AuditReport/blob/main/Smartcontract/TokimonsterAI Smarat Contract Audit Report-Exvul.pdf

Report Date: May 2025

Description:

The replace_user_reward_recipient function in TokimonsterRewarder fails to verify whether old_recipient and recipient are the same. This allows for address - replacement operations that are, in reality, non - operational. Such actions result in unnecessary gas consumption and the generation of invalid event logs.


Incorrect Display of Bridge Info

Severity: Low

Ecosystem: Sui

Protocol: Mango

Auditor: ExVul

Report: https://github.com/ExVul-Sec/AuditReport/blob/main/Smartcontract/Mango Smart Contract Audit Report-Exvul.pdf

Report Date: July 2025

Description:

In the config.move file, the pair_list function constructs a list of pairs by iterating through pair_id using a while loop. However, it fails to account for special pairs that may have been created using the create_special_bridge_pair function, where the specified id can be greater than the current pair_id. As a result, those special pairs are omitted during iteration. Ultimately, this leads to an incomplete BridgeInfo being returned in the bridge_info function of bridge.move.


Existence check problem

Severity: Low

Ecosystem: Sui

Protocol: Mango

Auditor: ExVul

Report: https://github.com/ExVul-Sec/AuditReport/blob/main/Smartcontract/Mango Smart Contract Audit Report-Exvul.pdf

Report Date: July 2025

Description:

In the treasury.move file, the add_treasury_cap function does not check if the same type already exists in treasuries. If so, it will abort. The function directly adds to the ObjectBag without checking if the key already exists, which will cause an abort if the treasury type already exists.


Faulty logic allows duplicate custodian addition

Severity: Low

Ecosystem: Sui

Protocol: Elixir

Auditor: Pashov Audit Group

Report: https://github.com/pashov/audits/blob/master/team/pdf/Elixir-security-review_2025-08-17.pdf

Report Date: Aug 2025

Description:

In deusd_minting.move function add_custodian_address_internal(), the incorrect assertion logic fails to prevent duplicate custodian addresses from being added.


Unavailable view function

Severity: Low

Ecosystem: Sui

Protocol: Elixir

Auditor: Pashov Audit Group

Report: https://github.com/pashov/audits/blob/master/team/pdf/Elixir-security-review_2025-08-17.pdf

Report Date: Aug 2025

Description:

The cooldown_underlying_amount and cooldown_end_time functions take a UserCooldown and return its underlying_amount and cooldown_end fields. However, these two view functions are actually unusable because UserCooldown is a field within SdeUSDManagement, which cannot be directly accessed by external modules. Moreover, the module does not contain any function that returns a reference to UserCooldown. Therefore, these two functions cannot be used in practice.


Soft restriction bypass via token transfers

Severity: Low

Ecosystem: Sui

Protocol: Elixir

Auditor: Pashov Audit Group

Report: https://github.com/pashov/audits/blob/master/team/pdf/Elixir-security-review_2025-08-17.pdf

Report Date: Aug 2025

Description:

In the sdeusd.move function add_to_blacklist() function soft-restricted users are only blocked from direct staking but can receive sdeUSD tokens via transfers, bypassing the restriction entirely.


Cooldown timer reset causes user withdrawal delays

Severity: Low

Ecosystem: Sui

Protocol: Elixir

Auditor: Pashov Audit Group

Report: https://github.com/pashov/audits/blob/master/team/pdf/Elixir-security-review_2025-08-17.pdf

Report Date: Aug 2025

Description:

In deusd_lp_staking.move function unstake() , each unstake operation overwrites the cooldown timestamp for all cooling tokens, not just the newly unstaked amount. If you check this vulnerable code, it resets the timer for ALL cooling tokens.


Cooldown duration changes apply retroactively

Severity: Low

Ecosystem: Sui

Protocol: Elixir

Auditor: Pashov Audit Group

Report: https://github.com/pashov/audits/blob/master/team/pdf/Elixir-security-review_2025-08-17.pdf

Report Date: Aug 2025

Description:

In deusd_lp_staking.move function withdraw() , the cooldown duration is read from current parameters at withdrawal time, not locked when user unstakes. Admin can change cooldown periods mid-stream, affecting users who have already begun cooling down. Let's check this scenario: 1. User unstakes 1000 tokens when cooldown = 30 days. 2. User expects withdrawal on Day 30. 3. Admin updates cooldown to 60 days on Day 20. 4. User tries withdrawing on Day 30 → fails because assert!(current_time >= stake_data.cooldown_start_timestamp + params.cooldown, ECooldownNotOver); now requires 60 days. The root cause is that params.cooldown always reads current global setting, not the duration that was active when the user started cooldown.


Security Levels Lack Flexibility

Severity: Low

Ecosystem: Sui

Protocol: BalancerV2

Auditor: Quantstamp

Report: https://certificate.quantstamp.com/full/bucket-protocol-v-2/abd312d6-1a5e-45c5-963b-a6856daf6621/index.html

Report Date: Aug 2025

Description:

The vault implements a three-level security system that provides insufficient granularity for emergency responses. Level 0 allows all operations, level 1 blocks everything, and level 2 blocks borrowing, repaying, and withdrawing while still allowing deposits and liquidations. This design may force administrators to disable critical functions unnecessarily.


pair::set_static_fee_parameters_internal updates volatility_accumulator to the new max value

Severity: Low

Ecosystem: Aptos

Protocol: Magma DEX

Auditor: Three Sigma

Report: https://cdn.sanity.io/files/qoqld077/staging/9566473c444a6cfd99c7a6556fa4857950b41de3.pdf

Report Date: July 2025

Description:

When updating the static fee parameters, we change a lot of variables including max_volatility_accumulator. After setting the new values, we change the volatility_accumulator to the new max_volatility_accumulator value, and we calculate the total_fees that will be accumulated at the max value. and making sure it do not exceeds MAX_TOTAL_FEE variable.


Insufficient vault balance validation in almm_rewarder::update_emission leads to overcommitted rewards and failed user claims

Severity: Low

Ecosystem: Aptos

Protocol: Magma DEX

Auditor: Three Sigma

Report: https://cdn.sanity.io/files/qoqld077/staging/9566473c444a6cfd99c7a6556fa4857950b41de3.pdf

Report Date: July 2025

Description:

The almm_rewarder::update_emission function validates vault balance before updating emission rates but fails to account for unclaimed rewards already promised to users. The function checks total vault balance without subtracting rewards accumulated through both PositionReward.amount_owned and the time-weighted growth calculation, allowing the protocol to overcommit rewards beyond available collateral.


Incorrect value capture order in set_protocol_variable_share leads to misleading event data

Severity: Low

Ecosystem: Aptos

Protocol: Magma DEX

Auditor: Three Sigma

Report: https://cdn.sanity.io/files/qoqld077/staging/9566473c444a6cfd99c7a6556fa4857950b41de3.pdf

Report Date: July 2025

Description:

The almm_pair::set_protocol_variable_share function updates the protocol variable share parameter but captures the old value after the parameter has already been modified. This causes the EventNewProtocolVariableFee event to emit identical values for both old_share and share fields.