YuzuUSD
Smart Contract Security Assessment
February 09, 2026

SUMMARY
ABSTRACT
Dedaub was commissioned to perform a security audit of the latest version of the Yuzu protocol, by Ouroboros and TelosC. No major issues were identified, although we do report low severity issues and advisories.
BACKGROUND
The YuzuUSD protocol under audit is a USDC-backed stablecoin ecosystem. It issues YuzuUSD, a stablecoin backed 1:1 by USDC. Users can stake YuzuUSD in the ERC4626-compliant StakedYuzuUSD vault to earn yield. To further enhance liquidity, USDC liquidity providers may participate in YuzuILP, an Insurance Liquidity Pool, and receive yield via the corresponding YuzuILP token. The protocol also includes orderbook functionality, enabling redemptions to be fulfilled by third parties through a three-step process. The protocol is centralized, with an admin responsible for several critical system functions.
The audit covers the V2 of the protocol, which adds important functionality with respect to the first version (although the core operations remain the same). The most prominent is a PSM module that allows instant staking and unstaking operations; users can send USDT, minting yzUSD and staking it to syzUSD, and vice versa. The PSM holds its own liquidity for instant operations, but also allows asynchronous orders filled by an admin. Cross-chain operations via LayerZero are added, as well as an emergency pause covering all user actions.
A previous audit by Dedaub of the first protocol version is available here: https://dedaub.com/audits/yuzu-money/yuzuusd-october-6-2025
SETTING & CAVEATS
This audit report mainly covers the contracts of the public https://github.com/Telos-Consilium/ouroboros-contracts/ repository of the Yuzu Protocol at commit 4614a5a997c7640c62619d71cdd1d05dd4d449a5 on branch v2. The target of the audit is evaluating the changes introduced in the following pull request of the repository: https://github.com/Telos-Consilium/ouroboros-contracts/pull/23
Audit Start Date: February 02, 2026
Audit End Date: February 05, 2026
Report Submission Date: February 09, 2026
2 auditors worked on the following contracts:
The audit’s main target is security threats, i.e., what the community understanding would likely call "hacking", rather than the regular use of the protocol. Functional correctness (i.e. issues in "regular use") is a secondary consideration. Typically it can only be covered if we are provided with unambiguous (i.e. full-detail) specifications of what is the expected, correct behavior. In terms of functional correctness, we often trusted the code’s calculations and interactions, in the absence of any other specification. Functional correctness relative to low-level calculations (including units, scaling and quantities returned from external protocols) is generally most effectively done through thorough testing rather than human auditing.
The auditing team also spent considerable time reviewing third party dependencies, which mainly covers:
- The LayerZero oVault integration introduced in the changes within the scope
- Any use of libraries
While those are assumed to be secure within the context of the engagement, a functional correctness issue regarding a specific OpenZeppelin library has been disclosed to the developers. In accordance with the principles of responsible disclosure, we have omitted the details from this report, having communicated directly with both OpenZeppelin and the protocol team. The severity is low, and we anticipate negligible adverse effects once the team implements the necessary precautions.
VULNERABILITIES & FUNCTIONAL ISSUES
This section details issues affecting the functionality of the contract. Dedaub generally categorizes issues according to the following severities, but may also take other considerations into account such as impact or difficulty in exploitation:
- User or system funds can be lost when third-party systems misbehave
- DoS, under specific conditions
- Part of the functionality becomes unusable due to a programming error
- Breaking important system invariants but without apparent consequences
- Buggy functionality for trusted users where a workaround exists
- Security issues which may manifest when the system evolves
CRITICAL SEVERITY
[No critical severity issues]
HIGH SEVERITY
[No high severity issues]
MEDIUM SEVERITY
[No medium severity issues]
LOW SEVERITY
Both YuzuProtoV2::burn and PSM::_redeem do not check on the pause status of yzUSD:
YuzuProtoV2::burnfunction burn(uint256 tokens) public virtual {
address _owner = _msgSender();
uint256 maxTokens = maxBurn(_owner);
if (tokens > maxTokens) {
revert ExceededMaxBurn(_owner, tokens, maxTokens);
}
_burn(_owner, tokens);
}
PSM::_redeemfunction _redeem(address caller, address receiver, address _owner, uint256 shares) internal returns (uint256) {
uint256 assets1 = _vault1.redeem(shares, address(this), _owner);
uint256 assets0 = _vault0.convertToAssets(assets1);
IERC20Burnable(address(_vault0)).burn(assets1);
SafeERC20.safeTransfer(IERC20(asset()), receiver, assets0);
...
}
Instead, the code relies on “implicit” checks, based on the possible code flow paths for reaching these methods. In particular, burn can only be called by the PSM, and inside the PSM such calls are protected by checking _canRedeem.
However, with such implicit checks it is easy to miss edge cases in rare execution flows. For instance, in the event that yzUSD is paused after a redemption order but before one gets filled, there will be no implicit checks on the pause status of YuzuUSDV2 when PSM::fillRedeemOrders is called:
PSM::fillRedeemOrders:253function fillRedeemOrders(uint256 assets, uint256[] calldata orderIds)
...
for (uint256 idx = 0; idx < orderIds.length; idx++) {
uint256 orderId = orderIds[idx];
_fillRedeemOrder(caller, orderId);
}
}
PSM::_fillRedeemOrder:344function _fillRedeemOrder(address caller, uint256 orderId) internal {
...
uint256 assets = _redeem(caller, order.receiver, address(this), order.shares);
...
}
This can lead to a situation in which redemptions are allowed even when the yzUSD contract is paused (but only if syzUSD has not been paused in the meantime).
Although this is a rare case with low severity consequences, we recommend adding explicit pause checks, to avoid not only this one but potentially more severe edges cases in the future.
While the StakedYuzuUSD contract has been deployed with a storage gap of 50 slots:
Plasma::0xb14e7d488371d22d39aff1b0c0f07ed2b532160f:414uint256[50] private __gap;
The same base contract now has 41 slots:
StakedYuzuUSD:411uint256[41] private __gap;
This makes it so that the following newly introduced storage variable in StakedYuzuUSDV2 contract occupies a slot within the previously allocated storage slots of the StakedYuzuUSD contract:
StakedYuzuUSDV2:15contract StakedYuzuUSDV2 is StakedYuzuUSD, IStakedYuzuUSDV2Definitions {
mapping(address => IntegrationConfig) internal integrations;
...
However, this breaks the standard guidelines for using storage gaps in upgradable contracts. The storage gap in each contract should only be used for variables added in the future to the same contract. Child contracts (eg StakedYuzuUSDV2) should not use the parent’s gap, they should have their own allocated space in the storage layout, and this space should remain the same across upgrades. Here, StakedYuzuUSDV2’s variables should be placed after the parent’s gap, not inside it.
In this particular case there are no security consequences by this violation. However, this is only due to the fact that StakedYuzuUSDV2 is a new contract with no previously allocated storage. Imagine, however, a third StakedYuzuUSDV3 version being created in the future: if StakedYuzuUSD’s gap is modified again, it would shift the variables of StakedYuzuUSDV2 leading to unpredictable behaviour. Another potentially problematic case are parent classes inherited by multiple subclasses: in such cases modifying the gap to accommodate variables in a new subclass will inadvertently modify the layout of the other subclasses.
To avoid future issues we recommend following the standard practice of modifying a contract’s gap only to add variables to the same contract (and not sub-contracts).
CENTRALIZATION CONSIDERATIONS
It is often desirable for DeFi protocols to assume no trust in a central authority, including the protocol’s owner. Even if the owner is reputable, users are more likely to engage with a protocol that guarantees no catastrophic failure even in the case the owner gets hacked/compromised. We list issues of this kind below. (These issues should be considered in the context of usage/deployment, as they are not uncommon. Several high-profile, high-value protocols have significant centralization threats.)
Similarly to several previous aspects of the protocol (insurance pool, order finalization, treasury, fees, tc), the newly added PSM is inherently centralized. The administrator, via a set of different roles (ADMIN_ROLE, REDEEM_MANAGER_ROLE, ORDER_FILLER_ROLE, LIQUIDITY_MANAGER_ROLE, etc), controls most aspects of the PSM. For instance, the administrator controls the PSM’s liquidity, needed for the instant operations, and he is also responsible for finalizing all asynchronous redemption orders.
OTHER / ADVISORY ISSUES
This section details issues that are not thought to directly affect the functionality of the project, but we recommend considering them.
The following snippet in the YuzuProto contract violates the typical convention of allocating one fixed-size storage array as space to be reserved for the introduction of future storage variables:
YuzuProto:430// slither-disable-next-line unused-state
uint256[45] private __gap0;
uint256[5] private __gap1;
While the source code supports all versions of 0.8.20 versions and above within the same minor version, the code is compiled with Solidity 0.8.30. Version 0.8.30, in particular, has some known bugs, which we do not believe affect the correctness of the contracts.
DISCLAIMER
The audited contracts have been analyzed using automated techniques and extensive human inspection in accordance with state-of-the-art practices as of the date of this report. The audit makes no statements or warranties on the security of the code. On its own, it cannot be considered a sufficient assessment of the correctness of the contract. While we have conducted an analysis to the best of our ability, it is our recommendation for high-value contracts to commission several independent audits, a public bug bounty program, as well as continuous security auditing and monitoring through Dedaub Security Suite.
ABOUT DEDAUB
Dedaub offers significant security expertise combined with cutting-edge program analysis technology to secure some of the most prominent protocols in DeFi. The founders, as well as many of Dedaub's auditors, have a strong academic research background together with a real-world hacker mentality to secure code. Protocol blockchain developers hire us for our foundational analysis tools and deep expertise in program analysis, reverse engineering, DeFi exploits, cryptography and financial mathematics.