ApxUSD security record

Arbitrumapyx.fiX

As of 30 Oct 2026, ApxUSD has 2 audit reports by 1 security firm on Trustblock; the latest is by Quantstamp, dated 30 Apr 2026. Those reports list no open critical findings.

Critical findings
No open critical findings
Across 2 reports.
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
Apyx – ApxUSD, ApyUSD, Bridged TokenSecurity firm: QuantstampDate: Scope: Files named in the reportNo open critical findingsOpen · certificate.quantstamp.com
ApxUSD StablecoinSecurity firm: QuantstampDate: Scope: Not recorded (see the report)No open critical findingsOpen · certificate.quantstamp.com

Findings18

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

SeverityOpenAcknowledgedFixed
Critical000
High001
Medium002
Low429
LowDeposits Accepted Before `unlockToken` Is Configured, Temporarily Blocking WithdrawalsApyx – ApxUSD, ApyUSD, Bridged Token · Quantstamp · 30 Apr 2026Acknowledged

`ApyUSD.initialize()` does not accept or set an `unlockToken` address. As documented in the NatSpec for `initialize()` (`@dev UnlockToken must be set after deployment using setUnlockToken()`), this is a post-deployment configuration step performed by `ADMIN_ROLE`. Until `setUnlockToken()` is called, every withdraw and redeem call reverts unconditionally: ```solidity // src/ApyUSD.sol:290-293 // Require unlockToken is set if (address($.unlockToken) == address(0)) { revert AddressNotSet("unlockToken"); } ``` The `vesting`, `unlockingFee`, and `feeWallet` parameters share this deferred-configuration pattern, but only the absence of `unlockToken` makes the vault non-functional for holders. The others have safe zero-value defaults (no yield accrual, no fee, fee retained in vault, respectively). This creates a window between deployment and `setUnlockToken` being called during which `deposit()` and `mint()` succeed, but `withdraw()` and `redeem()` are completely blocked.

Open the report
LowVesting Contract Rotation Potentially Strands Unvested Yield and Causes an Immediate Share Price DropApyx – ApxUSD, ApyUSD, Bridged Token · Quantstamp · 30 Apr 2026Acknowledged

`ApyUSD.setVesting()` replaces the stored vesting contract by overwriting `$.vesting` directly, with no prior claim of accrued yield from the outgoing contract: ```solidity // src/ApyUSD.sol:387-395 function setVesting(IVesting newVesting) external restricted { ApyUSDStorage storage $ = _getApyUSDStorage(); IVesting oldVesting = $.vesting; // Update Vesting reference $.vesting = newVesting; emit VestingUpdated(address(oldVesting), address(newVesting)); } ``` `LinearVestV0.pullVestedYield()` is gated by `onlyBeneficiary`, which checks `msg.sender == beneficiary`. The beneficiary is the `ApyUSD` vault address, set immutably at construction time. Once `$.vesting` is overwritten, the vault's `_withdraw` and `totalAssets` paths reference only the new contract. There is no protocol-level mechanism that will ever call `pullVestedYield()` on the old contract again, leaving its remaining balance permanently stranded under normal operation. The impact is two-fold: 1. **Immediate share price discontinuity:** `totalAssets()` includes `$.vesting.vestedAmount()` as phantom yield, tokens physically held by the vesting contract but logically attributed to the vault's share price: ```solidity // src/ApyUSD.sol:200-211 function totalAssets() public view override returns (uint256) { ... if (address($.vesting) != address(0)) { vestedYield = $.vesting.vestedAmount(); } return vaultBalance + vestedYield; } ``` At the moment `setVesting` executes, `$.vesting` changes atomically. If the outgoing contract held `V` in `vestedAmount()`, `totalAssets()` drops by `V` in the same transaction. Because `totalSupply()` is unchanged, each outstanding share is immediately redeemable for fewer assets. A loss of value for all current holders proportional to `V / totalSupply`. 2. **Stranded unvested yield:** Beyond the already-vested portion, any yield still in the unvested tranche (`LinearVestV0.unvestedAmount()`) is locked in the old contract indefinitely. There is no admin function on `ApyUSD` to trigger `pullVestedYield` on an arbitrary address, and `LinearVestV0.pullVestedYield` cannot be called by anyone other than the registered beneficiary. The tokens remain in the old contract, inaccessible through any normal protocol flow.

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.

The repositories and 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="apxusd"
></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