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.
Record last updated . It holds audits and findings, contracts and incidents up to Oct 2026. Trustblock does not review code.
Newest first
| Audit | Security firm | Date | Scope | Critical findings | Report |
|---|---|---|---|---|---|
| Apyx – ApxUSD, ApyUSD, Bridged Token | Security firm: Quantstamp | Date: | Scope: Files named in the report | No open critical findings | Open · certificate.quantstamp.com |
| ApxUSD Stablecoin | Security firm: Quantstamp | Date: | Scope: Not recorded (see the report) | No open critical findings | Open · certificate.quantstamp.com |
Statuses are the security firm’s own, from each report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 0 |
| High | 0 | 0 | 1 |
| Medium | 0 | 0 | 2 |
| Low | 4 | 2 | 9 |
`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`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 reportThe reports name a repository or files. Open a report to see its scope.
Is this your project? Show this record on your own website. The label states what the record holds, links to this page and updates by itself. It is free and needs no sign-in.
Automatic: the three strongest facts of this project’s own record (its last audit and two more), highlighted. They update with the record. Picking a fact turns Automatic off.
<head><script src="https://widget.trustblock.run/project-widget.min.js" defer></script></head><body><divdata-tb-project-widgetdata-tb-project-slug="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