Tapir security record

Ethereumtapir.money

As of 30 Oct 2026, Tapir has 1 audit report on Trustblock, by Quantstamp, dated 6 Jan 2026. That report lists no open critical findings.

Critical findings
No open critical findings
In 1 report.
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.

Audits1

Newest first

AuditSecurity firmDateScopeCritical findingsReport
tapir protocolSecurity firm: QuantstampDate: Scope: Not recorded (see the report)No open critical findingsOpen · certificate.quantstamp.com

Findings9

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

SeverityOpenAcknowledgedFixed
Critical000
High003
Medium003
Low003
HighIncorrect Protocol Fee Calculation in the `sweepFeesToTreasury()` Function Allows `DepegPool` to Become Undercollateralizedtapir protocol · Quantstamp · 6 Jan 2026Fixed

The logic of the `sweepFeesToTreasury()` function calculates how many of the `ASSET` tokens held in the contract can be transferred to the treasury as earned fees. However, due to an error in how this amount is calculated, `feeAmount` will be half of the total `ASSET` tokens in the contract. This is because `dpSupply` and `ybSupply` are expected to be 50% of the contract's total `ASSET` balance. As this function is permissionless and can be called at state in the protocols lifecycle, there is a significant risk of griefing where funds can be repeatedly forced to the treasury, leaving the protocol under-collateralized.

Open the report
HighManual Resolution of PTRW Not Possible Due To State Reversion in the `resolvePtrw()` Function, Locking User Fundstapir protocol · Quantstamp · 6 Jan 2026Fixed

In the `resolvePtrw()` function, if the attempt to redeem PT tokens from Pendle fails (no tokens are redeemed), a manual price resolve is required. However, in the current implementation, the `resolvePtrw()` function immediately reverts after setting `forceManualResolve = true`, rewinding all state transitions made during the function call, including the setting of the `forceManualResolve` boolean. This means that in scenarios where a manual resolution is necessary, if the `pendlePT` balance of the `TapirPtrwOracle` contract is non-zero it will not be possible to execute a manual resolution, leaving the oracle contract in a deadlocked state where the oracle contract cannot write price data to the `DepegPool` contract.

Open the report
HighThe `DepegPool` Contract's `MIN_PRICE` Constraint Can Cause a Deadlock Where the `updatePriceData()` Function Cannot Complete in the Event of a Large Depeg Event, Locking User Fundstapir protocol · Quantstamp · 6 Jan 2026Fixed

The `DepegPool` contract has a `MIN_PRICE` that the underlying asset must be when the `TapirOracle` provides the final price data via the `updatePriceData()` function. However, if there is a significant depeg event there is no guarantee that the price of the underlying asset will be greater than `MIN_PRICE`. In this scenario, the `DepegPool` contract will not be able to progress into the `REDEMPTION` stage, preventing users from withdrawing their funds.

Open the report
Medium`_cfg.maxPriceStaleness` May Incorrectly Include or Exclude Price Sources that Have Different Update Heartbeatstapir protocol · Quantstamp · 6 Jan 2026Fixed

In `TapirOracle.checkpoint()`, checks are made to ensure the price provided by an oracle has been updated within a specific `maxPriceStaleness`. However, different price feeds will have different update tolerances (heartbeats), where if the price has not moved outside of the accepted tolerance, the oracle will not be updated unnecessarily until the heartbeat time. This could lead to the `checkpoint()` function mistakenly considering a price stale while it is still actually valid. Alternatively, if the `maxPriceStaleness` was too large for a specific price source, a stale price might be considered valid by the Tapir oracle.

Open the report
Medium`minPriceAge` Manipulation Prevents Pool Resolutiontapir protocol · Quantstamp · 6 Jan 2026Fixed

The `minPriceAge` parameter is mutable via `setMinPriceAge()` without state guards. The `resolvePriceDepeg()` function requires `block.timestamp - finalPriceData.timestamp >= minPriceAge` before allowing resolution. When an admin increases `minPriceAge` (up to MAX_DURATION = 30 days) while the pool is in RESOLUTION state, the function reverts with `PriceDataTooRecent`, indefinitely blocking progression to REDEMPTIONS and effectively locking user funds. Unlike HIGH-01 (backwards transition), this freezes the state machine in RESOLUTION.

Open the report
MediumUse of Yield Bearing Assets Could Cause Users Unexpected Shortcomingstapir protocol · Quantstamp · 6 Jan 2026Fixed

When the `ASSET` token of a `DepegPool` instance is a yield bearing asset users are likely to face a `successFee` upon redemption which takes a percentage fee of the users redeemable amount based on the price increase of the underlying asset from the `startingPrice` when the pool was deployed. For users who deposit towards the end of the pools `activeDuration` they will still be forced to pay the full `successFee` even though the majority of the value accrual occurred before the user's assets were added to the pool. This potential risk is not clearly outlined to the user who may end up with less `ASSET` tokens than they originally deposited due to the `successFee`.

Open the report
LowDynamic Fee Oracle Inconsistencytapir protocol · Quantstamp · 6 Jan 2026Fixed

Pools used as price oracles should document the dual-fee system: ```solidity uint24 public immutable override fee; // Pool identifier uint24 public override dynamicFee; // Actual swap fee ``` For Oracle Integrators: - Use `fee()` for pool identification and tick spacing - Use `dynamicFee()` for actual swap cost calculations - TWAP calculations are unaffected (based on price, not fees)

Open the report
LowState Machine Transition Function Is Not Monotonictapir protocol · Quantstamp · 6 Jan 2026Fixed

The protocol expected a strict linear progression from the state machine as follows: 1 (`STATE_ACTIVE`) → 2 (`STATE_COOLDOWN`) → 3 (`STATE_RESOLUTION`) → 4 (`STATE_REDEMPTIONS`). However, because the protocol's admin is able to change the `cooldownDuration` at any time, the project could theoretically move from a later state back to `STATE_COOLDOWN`. Due to how the current state is assessed in the `getState()` function, it is possible to end up with a transition from `STATE_RESOLUTION` → `STATE_COOLDOWN `(3 → 2) and from `STATE_REDEMPTIONS` → `STATE_COOLDOWN` (4 → 2).

Open the report
LowUnnecessary Storage Packing of Constant and Immutable Variablestapir protocol · Quantstamp · 6 Jan 2026Fixed

The `DepegPool` contract packs its storage variables for a more efficient storage layout. However, it also unnecessarily packs variables marked as `constant` and `immutable`. This is unnecessary as both constant and immutable variables in solidity are compiled directly into the contract's bytecode rather than being held in the contract's storage onchain.

Open the report

Contracts

No deployed address is recorded for these audits.

The reports name a repository or files. Open a report to see its scope.

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="tapir"
></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