# Table of Contents
- [Welcome to Ondo | Ondo Finance](#welcome-to-ondo-ondo-finance)
- [Trust & Security | Ondo Finance](#trust-security-ondo-finance)
- [Ondo Global Markets | Ondo Finance](#ondo-global-markets-ondo-finance)
- [Overview | Ondo Finance](#overview-ondo-finance)
- [Comparison to Other Tokenized Stocks | Ondo Finance](#comparison-to-other-tokenized-stocks-ondo-finance)
- [Eligibility | Ondo Finance](#eligibility-ondo-finance)
- [Investing & Redeeming | Ondo Finance](#investing-redeeming-ondo-finance)
- [Market Hours & Trading Availability | Ondo Finance](#market-hours-trading-availability-ondo-finance)
- [Available Assets | Ondo Finance](#available-assets-ondo-finance)
- [Onboarding & KYC | Ondo Finance](#onboarding-kyc-ondo-finance)
- [Transferability | Ondo Finance](#transferability-ondo-finance)
- [Token & Quote Pricing | Ondo Finance](#token-quote-pricing-ondo-finance)
- [Corporate Actions | Ondo Finance](#corporate-actions-ondo-finance)
- [Fees & Taxes | Ondo Finance](#fees-taxes-ondo-finance)
- [Technical | Ondo Finance](#technical-ondo-finance)
- [Trust & Transparency | Ondo Finance](#trust-transparency-ondo-finance)
- [Legal & Regulatory | Ondo Finance](#legal-regulatory-ondo-finance)
- [Partners & Media | Ondo Finance](#partners-media-ondo-finance)
- [Troubleshooting | Ondo Finance](#troubleshooting-ondo-finance)
- [Disclaimer | Ondo Finance](#disclaimer-ondo-finance)
- [Ondo Chain | Ondo Finance](#ondo-chain-ondo-finance)
- [Special Terms Relating to the Acquisition of Tokens on the Secondary Market: | Ondo Finance](#special-terms-relating-to-the-acquisition-of-tokens-on-the-secondary-market-ondo-finance)
- [Ondo Chain Overview | Ondo Finance](#ondo-chain-overview-ondo-finance)
- [Ondo Chain FAQ | Ondo Finance](#ondo-chain-faq-ondo-finance)
- [USDY Token | Ondo Finance](#usdy-token-ondo-finance)
- [General-Access Products | Ondo Finance](#general-access-products-ondo-finance)
- [USDY Basics | Ondo Finance](#usdy-basics-ondo-finance)
- [Comparison to Stablecoins | Ondo Finance](#comparison-to-stablecoins-ondo-finance)
- [USDY vs Rebasing USDY (rUSDY) | Ondo Finance](#usdy-vs-rebasing-usdy-rusdy-ondo-finance)
- [Rebasing | Ondo Finance](#rebasing-ondo-finance)
- [Faq | Ondo Finance](#faq-ondo-finance)
- [Ondo USDY LLC | Ondo Finance](#ondo-usdy-llc-ondo-finance)
- [Onboarding & KYC | Ondo Finance](#onboarding-kyc-ondo-finance)
- [Investing & Redeeming | Ondo Finance](#investing-redeeming-ondo-finance)
- [USDY Legal Disclaimer | Ondo Finance](#usdy-legal-disclaimer-ondo-finance)
- [USDYc | Ondo Finance](#usdyc-ondo-finance)
- [Transfers | Ondo Finance](#transfers-ondo-finance)
- [Economics & Fees | Ondo Finance](#economics-fees-ondo-finance)
- [Technology | Ondo Finance](#technology-ondo-finance)
- [Trust & Transparency | Ondo Finance](#trust-transparency-ondo-finance)
- [Partners & Media | Ondo Finance](#partners-media-ondo-finance)
- [Minting & Redeeming | Ondo Finance](#minting-redeeming-ondo-finance)
- [Overview | Ondo Finance](#overview-ondo-finance)
- [Qualified-Access Products | Ondo Finance](#qualified-access-products-ondo-finance)
- [Cash Management 101 | Ondo Finance](#cash-management-101-ondo-finance)
- [Eligibility | Ondo Finance](#eligibility-ondo-finance)
- [Onboarding & KYC | Ondo Finance](#onboarding-kyc-ondo-finance)
- [Ousg | Ondo Finance](#ousg-ondo-finance)
- [Fees & Taxes | Ondo Finance](#fees-taxes-ondo-finance)
- [Eligibility & Onboarding | Ondo Finance](#eligibility-onboarding-ondo-finance)
- [Investing | Ondo Finance](#investing-ondo-finance)
- [Redeeming | Ondo Finance](#redeeming-ondo-finance)
- [Instant Minting and Redemption Limits | Ondo Finance](#instant-minting-and-redemption-limits-ondo-finance)
- [Yield | Ondo Finance](#yield-ondo-finance)
- [OUSG vs Rebasing OUSG (rOUSG) | Ondo Finance](#ousg-vs-rebasing-ousg-rousg-ondo-finance)
- [Technical | Ondo Finance](#technical-ondo-finance)
- [Rebasing | Ondo Finance](#rebasing-ondo-finance)
- [Regulatory Compliance | Ondo Finance](#regulatory-compliance-ondo-finance)
- [OUSG Legal Disclaimer | Ondo Finance](#ousg-legal-disclaimer-ondo-finance)
- [Trust & Transparency | Ondo Finance](#trust-transparency-ondo-finance)
- [Other | Ondo Finance](#other-ondo-finance)
- [Protocols | Ondo Finance](#protocols-ondo-finance)
- [Flux Finance | Ondo Finance](#flux-finance-ondo-finance)
- [Developer Guides | Ondo Finance](#developer-guides-ondo-finance)
- [Ondo Token Tools (Bridge and Converter) | Ondo Finance](#ondo-token-tools-bridge-and-converter-ondo-finance)
- [Ondo Token Bridge | Ondo Finance](#ondo-token-bridge-ondo-finance)
- [Integration Guidelines for Protocols Supporting USDY on Mantle | Ondo Finance](#integration-guidelines-for-protocols-supporting-usdy-on-mantle-ondo-finance)
- [Ondo Token Converter | Ondo Finance](#ondo-token-converter-ondo-finance)
- [USDY and mUSD Conversion | Ondo Finance](#usdy-and-musd-conversion-ondo-finance)
- [Legal | Ondo Finance](#legal-ondo-finance)
- [Smart Contract Addresses | Ondo Finance](#smart-contract-addresses-ondo-finance)
- [Ondo V1 - Vaults & LaaS | Ondo Finance](#ondo-v1-vaults-laas-ondo-finance)
- [Ondo Summit 2026 Terms | Ondo Finance](#ondo-summit-2026-terms-ondo-finance)
- [Cookies Policy | Ondo Finance](#cookies-policy-ondo-finance)
- [Privacy Policy | Ondo Finance](#privacy-policy-ondo-finance)
- [Terms of Service | Ondo Finance](#terms-of-service-ondo-finance)
- [Disclaimers | Ondo Finance](#disclaimers-ondo-finance)
- [Unknown](#unknown)
- [Unknown](#unknown)
- [Smart Contract Audits | Ondo Finance](#smart-contract-audits-ondo-finance)
- [Unknown](#unknown)
- [Unknown](#unknown)
- [Unknown](#unknown)
- [Unknown](#unknown)
- [Unknown](#unknown)
- [Unknown](#unknown)
- [Unknown](#unknown)
- [Unknown](#unknown)
- [Unknown](#unknown)
- [404: This page could not be found](#404-this-page-could-not-be-found)
- [404: This page could not be found](#404-this-page-could-not-be-found)
---
# Welcome to Ondo | Ondo Finance
Welcome to Ondo
Welcome to Ondo
===============
At Ondo, our mission is to make institutional-grade financial products and services available to everyone. We believe that blockchain technology has the potential to improve both the infrastructure of — and access to — financial products and services. We also believe that the best technical improvements need to be combined with the best practices from traditional finance, including investor protections, transparency in reporting, legal and regulatory compliance, intelligent and robust product structuring, working with the best service providers, and top-notch client service.
To help us do this, we have an **asset management** arm that creates and manages tokenized financial products as well as a **technology arm** that develops decentralized finance protocols.
Products[](https://docs.ondo.finance/#products)
------------------------------------------------
To get started with our products, simply browse the list of available funds on our [website (opens in a new tab)](https://ondo.finance/)
or listed here in these docs. You'll be able to find detailed information, including what assets underlie each, how they work, expected yields and risks, eligibility requirements, and much more.
When you find a product you like, once you onboard you can invest by connecting your wallet and depositing stablecoins (or, in some cases, wiring USD). When you wish to redeem your tokens for stablecoins (or USD), you can request a redemption. How long it takes to redeem your tokens depends on the particular product.
Protocols[](https://docs.ondo.finance/#protocols)
--------------------------------------------------
The protocols we create are set up to eventually run independently from Ondo. Each protocol has its own separate web app interface on a different web domain governed by a separate entity not controlled by Ondo. When you click on any of the protocols, therefore, you'll notice they open in a different browser window/tab, managed by external parties. The details of any individual protocol can be found on the appropriate site.
Learn More[](https://docs.ondo.finance/#learn-more)
----------------------------------------------------
You can find out more about Ondo and our offerings by reading through these docs or by visiting our website at [https://ondo.finance (opens in a new tab)](https://ondo.finance/)
.
Join Our Community[](https://docs.ondo.finance/#join-our-community)
--------------------------------------------------------------------
We'd love to hear from you. Please consider joining us on [Twitter (opens in a new tab)](https://twitter.com/OndoFinance)
and/or [Telegram (opens in a new tab)](https://t.me/ondofinance)
. You can also contact us at [support@ondo.finance](mailto:support@ondo.finance)
Last updated on August 25, 2025
[Trust & Security](https://docs.ondo.finance/trust-and-security "Trust & Security")
---
# Trust & Security | Ondo Finance
Trust & Security
Trust & Security
================
When dealing with money, trust and security are always important. In crypto, these issues are even more top of mind. We therefore wanted to highlight a few of the many ways we are committed to maintaining your trust and the security of your funds.
Institutional Partners[](https://docs.ondo.finance/trust-and-security#institutional-partners)
----------------------------------------------------------------------------------------------
Even within TradFi, setting up and operating any given fund involves many parties, such as asset managers, custodians, fund administrators, counterparties, lawyers, and more. And that list only gets bigger in onchain finance, particularly when connecting onchain capital to off-chain assets. Simply put, partners matter.
At Ondo, we work with only the most reputable, well-established partners across all functions. For instance, with OUSG (Ondo Short-Term US Government Treasuries), the USDC you invest is exchanged for USD primarily by Coinbase, one of the leading crypto asset custodians, or Circle, the issuer of USDC. Furthermore, the majority of the Fund’s assets are currently invested in the BlackRock USD Institutional Digital Liquidity Fund (BUIDL), managed and sponsored by BlackRock, one of the world's preeminent asset management firms and a premier provider of investment management services. The Fund’s assets are also invested with reputable, highly regarded entities such as Fidelity, Franklin Templeton, and WisdomTree. Additionally, US Treasuries - the primary underlying assets of the Fund’s investments - are backed by the full faith and credit of the United States government, and largely considered to be one of the lowest-risk assets in the world.
For all of our products, the principle is the same: high quality institutional partners, always.
Transparency & Disclosure[](https://docs.ondo.finance/trust-and-security#transparency--disclosure)
---------------------------------------------------------------------------------------------------
We believe the standards for transparency and disclosure in onchain finance should meet or exceed those in TradFi. Whenever possible, we try to be transparent with our product and protocol details. As an example, if you visit the product page for any of our funds, you will find detailed information on all relevant dimensions, including the strategy employed, the underlying portfolio composition, historical performance and risk, as well as the results of periodic fund audits. On the technical side, our smart contracts have successfully completed audits from some of the leading firms in the industry, and these audits are published here: [https://docs.ondo.finance/audits (opens in a new tab)](https://docs.ondo.finance/audits)
. Finally, Ondo and its related entities regularly undergo financial and information security audits, which are shared with authorized requesting parties.
Legal & Regulatory Compliance[](https://docs.ondo.finance/trust-and-security#legal--regulatory-compliance)
-----------------------------------------------------------------------------------------------------------
At Ondo, we know that legal and regulatory compliance is a critical pillar of tokenized real-world-asset offerings. We take a thorough and measured approach to risk management in general, with a compliance-oriented product design that is rooted in consultation with a variety of legal, tax, and regulatory experts.
### Ondo I LP (OUSG)[](https://docs.ondo.finance/trust-and-security#ondo-i-lp-ousg)
The Fund is structured using a traditional GP/LP model. Investors become limited partners in the Fund by acquiring OUSG tokens, each of which represents a unitized limited partnership interest in the Fund. The Fund is managed by its General Partner, Ondo I GP LLC, a Delaware limited liability company and wholly owned subsidiary of Ondo Finance. The Fund’s Investment Manager is Ondo Capital Management LLC, a Delaware limited liability company and wholly owned subsidiary of Ondo Finance. Proceeds of each purchase of OUSG from the Fund are invested by the Investment Manager into US Treasuries products.
The Fund is further structured as a private fund under Section 3(c)(7) of the Investment Company Act of 1940 (the “40 Act”), which exempts the Fund from registration as an investment company. Accordingly, OUSG is only available to Qualified Purchasers as defined in the 40 Act. OUSG is offered and sold by the Fund in reliance on Rule 506(c) of Regulation D under the Securities Act of 1933 (the “33 Act”), which exempts OUSG from the securities registration requirements. Accordingly, OUSG can only be acquired by verified Accredited Investors as defined in Regulation D. Investors also must undergo customer due diligence for anti-money laundering, countering terrorist financing, and sanctions compliance purposes, which is administered by the General Partner.
### Ondo USDY LLC (USDY)[](https://docs.ondo.finance/trust-and-security#ondo-usdy-llc-usdy)
Ondo USDY LLC (the “USDY entity”) is structured as a special purpose vehicle whose activities are limited to (1) borrowing funds from prospective lenders, (2) issuing USDY tokens to evidence the LLC’s debt obligations to those lenders, (3) allocating the proceeds of borrowing to US Treasuries and US bank demand deposits, (4) creating and perfecting a security interest in its assets, and (5) related incidental activities.
USDY is offered and sold by the USDY entity in reliance on Regulation S under the 33 Act, which exempts USDY from the securities registration requirements. Accordingly, USDY can only be issued and sold by the LLC to non-US persons in transactions outside the US. Ondo USDY LLC is also registered as a money services business with the Financial Crimes Enforcement Network of the US Department of the Treasury (“FinCEN”). Investors also must undergo customer due diligence for anti-money laundering, countering terrorist financing, and sanctions compliance purposes in accordance with the anti-money laundering program that the LLC has adopted to comply with the US Bank Secrecy Act.
Last updated on August 25, 2025
[Welcome to Ondo](https://docs.ondo.finance/ "Welcome to Ondo")
[Ondo Global Markets](https://docs.ondo.finance/ondo-global-markets "Ondo Global Markets")
---
# Ondo Global Markets | Ondo Finance
Ondo Global Markets
Ondo Global Markets
===================
[📄 Overview\
-----------\
\
An overview of Ondo Global Markets](https://docs.ondo.finance/ondo-global-markets/overview)
[📄 Comparison to Other Tokenized Stocks\
---------------------------------------\
\
How does Ondo Global Markets compare to other tokenized stocks?](https://docs.ondo.finance/ondo-global-markets/comparison-to-other-tokenized-stocks)
[📄 Eligibility\
--------------\
\
Who can acquire or redeem Ondo Global Markets tokens?](https://docs.ondo.finance/ondo-global-markets/eligibility)
[📄 Investing & Redeeming\
------------------------\
\
How to acquire and redeem Ondo Global Markets tokens?](https://docs.ondo.finance/ondo-global-markets/investing-and-redeeming)
[📄 Market Hours & Trading Availability\
--------------------------------------\
\
What are the market hours and trading availability?](https://docs.ondo.finance/ondo-global-markets/market-hours-and-trading-availability)
[📄 Available Assets\
-------------------\
\
What assets are available on Ondo Global Markets?](https://docs.ondo.finance/ondo-global-markets/available-assets)
[📄 Onboarding & KYC\
-------------------\
\
What is required for onboarding and KYC?](https://docs.ondo.finance/ondo-global-markets/onboarding-and-kyc)
[📄 Transferability\
------------------\
\
Are Ondo Global Markets tokens transferable?](https://docs.ondo.finance/ondo-global-markets/transferability)
[📄 Token & Quote Pricing\
------------------------\
\
How do token and quote pricing work?](https://docs.ondo.finance/ondo-global-markets/token-and-quote-pricing)
[📄 Corporate Actions\
--------------------\
\
What are corporate actions and how are they handled?](https://docs.ondo.finance/ondo-global-markets/corporate-actions)
[📄 Fees & Taxes\
---------------\
\
What fees and taxes are applicable to Ondo Global Markets?](https://docs.ondo.finance/ondo-global-markets/fees-and-taxes)
[📄 Technical\
------------\
\
On which chains is Global Markets available, and are the smart contracts audited?](https://docs.ondo.finance/ondo-global-markets/technical)
[📄 Trust & Transparency\
-----------------------\
\
What types of protections and reporting are provided?](https://docs.ondo.finance/ondo-global-markets/trust-and-transparency)
[📄 Legal & Regulatory\
---------------------\
\
What is the legal structure, and how does Ondo Global Markets remain regulatorily compliant?](https://docs.ondo.finance/ondo-global-markets/legal-and-regulatory)
[📄 Partners & Media\
-------------------\
\
Who should partners and media contact?](https://docs.ondo.finance/ondo-global-markets/partners-and-media)
[📄 Troubleshooting\
------------------\
\
How can I solve an issue I'm experiencing?](https://docs.ondo.finance/ondo-global-markets/troubleshooting)
[📄 Disclaimer\
-------------\
\
Legal Disclaimer](https://docs.ondo.finance/ondo-global-markets/disclaimer)
Last updated on September 2, 2025
[Trust & Security](https://docs.ondo.finance/trust-and-security "Trust & Security")
[Overview](https://docs.ondo.finance/ondo-global-markets/overview "Overview")
---
# Overview | Ondo Finance
[Ondo Global Markets](https://docs.ondo.finance/ondo-global-markets)
Overview
Overview
========
### What is Ondo Global Markets?[](https://docs.ondo.finance/ondo-global-markets/overview#what-is-ondo-global-markets)
Ondo Global Markets (Ondo GM) is a tokenization platform designed to provide onchain exposure to publicly traded securities. The platform will enable investors [outside the US](https://docs.ondo.finance/ondo-global-markets/eligibility)
to gain exposure to thousands of US publicly traded securities, including stocks and ETFs. By providing tokenized exposure to these assets, Ondo Global Markets brings the transparency, efficiency, and accessibility enabled by blockchain technology to institutional-grade finance. Through its APIs and SDKs, the platform also empowers third-party developers to build innovative financial applications, making it a cornerstone for the next generation of financial services.
### What are Ondo tokenized stocks?[](https://docs.ondo.finance/ondo-global-markets/overview#what-are-ondo-tokenized-stocks)
Ondo tokenized stocks (when we say ‘stocks’ we are also referring to ETFs and other publicly traded securities, for convenience) are tokens issued by the Ondo Global Markets platform. They are designed to give holders the same economic exposure as they would receive if they owned the underlying asset and invested dividends back into the stock (net of [withholding tax](https://docs.ondo.finance/ondo-global-markets/fees-and-taxes#how-are-ondo-tokenized-stocks-taxed)
). They are designated by the `on` suffix. For example, the stock ticker for Tesla is `TSLA`, therefore the corresponding Ondo tokenized stock is called `TSLAon` . You can think of the `on` suffix as standing for onchain or Ondo—whichever you prefer.
### What are the most important things I should know?[](https://docs.ondo.finance/ondo-global-markets/overview#what-are-the-most-important-things-i-should-know)
* **Ondo tokenized stocks are designed differently than many other tokenized stocks.** They are designed to be as liquid as the underlying assets, minimizing slippage and price deviation from the underlying assets they represent. [Learn more](https://docs.ondo.finance/ondo-global-markets/comparison-to-other-tokenized-stocks)
.
* **One token does not necessarily represent the value of one share, and the price of one token will not always match the price of the underlying asset.** Ondo tokenized stocks are _fully backed_ with the underlying asset (together with any cash in transit), but they are what is known as _total return trackers;_ they are meant to provide tokenholders with the same economics as holding the underlying asset _and_ investing any dividends back into the stock (net of [withholding taxes](https://docs.ondo.finance/ondo-global-markets/fees-and-taxes#how-are-ondo-tokenized-stocks-taxed)
). Therefore, over time, a given token may provide economic exposure to _more than_ one share, and the price of the token and the underlying stock are likely to diverge. [Learn more](https://docs.ondo.finance/ondo-global-markets/token-and-quote-pricing#how-is-the-price-of-an-ondo-tokenized-stock-determined)
* **They generally trade 24/5, but there are exceptions.** There can be short pauses in trading between trading sessions, during corporate actions (like dividends and stock splits), if certain platform risk limits are hit, etc. You can always see the latest status at [status.ondo.finance (opens in a new tab)](https://status.ondo.finance/)
. [Learn More](https://docs.ondo.finance/ondo-global-markets/market-hours-and-trading-availability)
* **There are no mint or burn fees.** When you buy or sell an Ondo tokenized stock, the quoted price is the price you will pay (or receive), though this may differ slightly from the price at which we buy (or sell) the underlying. [Learn more](https://docs.ondo.finance/ondo-global-markets/fees-and-taxes)
* **Minting and burning are instant.** When you buy or sell Ondo tokenized stocks, you get your tokens or stablecoins in a single atomic transaction. [Learn more](https://docs.ondo.finance/ondo-global-markets/investing-and-redeeming#what-forms-of-payment-can-i-use-to-purchase-ondo-tokenized-stocks)
* **You can buy fractional tokens.** You do not need to purchase full tokens.
* **They are currently available on Ethereum and BNB Chain, but will be available on other chains soon.** Solana and others are coming soon.
* **There are currently 100+ assets available, but more are coming soon.** The Ondo Global Markets platform is designed to be highly scalable. In the coming months expect many more assets to come online. [Learn More](https://docs.ondo.finance/ondo-global-markets/available-assets)
* **They are designed to give you economic exposure to the underlying asset, not direct title to them.** While you can redeem your Tokens for cash or stablecoins for the then-value of the underlying assets, you do not receive shareholder voting rights, statutory information rights or other shareholder rights from the issuer of those securities. [Learn more](https://docs.ondo.finance/ondo-global-markets/legal-and-regulatory#does-this-mean-the-tokenholder-does-not-actually-own-the-underlying-asset)
* **They are generally available to non-US investors.** Subject to certain jurisdictional and other restrictions. [Learn more](https://docs.ondo.finance/ondo-global-markets/eligibility)
* **They are transferrable and DeFi compatible.** Ondo tokenized stocks are designed to be usable in DeFi protocols that support them. For example, they could be used as collateral for lending or in perps protocols.
* **They are being launched with an ecosystem of partners.** Ondo tokenized stocks are being launched in partnership with many participants of the Ondo Ecosystem, including Bitget, Trust Wallet, OKX, HTX Global, 1inch, CoW Protocol, Ledger, BitGo, CoinGecko, Morpho, Gauntlet, Alpaca Markets, and others.
* **To buy or sell them directly from the platform, you must complete the Ondo Global Markets know-your-customer (KYC) onboarding process.** Currently, onboarding is only open to institutional participants; onboarding for retail users and individuals is coming soon. [Learn more](https://docs.ondo.finance/ondo-global-markets/onboarding-and-kyc)
* **They are designed with best-in-class investor protections.** Ondo tokenized stocks offer a bankruptcy-remote legal structure using a special purpose vehicle with at least one independent director, full asset backing with overcollateralization, a first-priority security interest held by a third-party security agent, daily attestations of assets held at regulated US entities, rigorously audited smart contracts, and transparent reporting via daily updates, monthly reconciliations, and annual audits. [Learn more](https://docs.ondo.finance/ondo-global-markets/trust-and-transparency)
Last updated on October 28, 2025
[Ondo Global Markets](https://docs.ondo.finance/ondo-global-markets "Ondo Global Markets")
[Comparison to Other Tokenized Stocks](https://docs.ondo.finance/ondo-global-markets/comparison-to-other-tokenized-stocks "Comparison to Other Tokenized Stocks")
---
# Comparison to Other Tokenized Stocks | Ondo Finance
[Ondo Global Markets](https://docs.ondo.finance/ondo-global-markets)
Comparison to Other Tokenized Stocks
Comparison to Other Tokenized Stocks
====================================
### How do slippage, liquidity, and price dislocations interconnect in tokenized asset markets, and why do they pose challenges for early tokenized stocks?[](https://docs.ondo.finance/ondo-global-markets/comparison-to-other-tokenized-stocks#how-do-slippage-liquidity-and-price-dislocations-interconnect-in-tokenized-asset-markets-and-why-do-they-pose-challenges-for-early-tokenized-stocks)
In tokenized asset markets, slippage, liquidity, and price dislocations are interconnected concepts that can significantly impact trading efficiency and price stability, so understanding their relationships is crucial for investors.
Let’s start by defining some terms. _Liquidity_ refers to how easily an asset can be bought or sold without drastically affecting its price. (For example, if you were trying to sell your house within the next day, you’d probably have to sell it for a _lot_ less than if you ran a normal sales process. This is one reason why your house is considered an illiquid asset.) In public markets, liquidity is often characterized by market depth (the volume available at various price levels), bid-ask spreads (the gap between buy and sell prices), and trading volume (how many shares are trading in a given time period). High liquidity allows for smooth transactions, while low liquidity creates vulnerabilities. In tokenized stocks, liquidity is often "recreated" onchain, separate from the deep pools in traditional exchanges like NASDAQ, leading to thin order books (e.g. having few buy or sell orders at various prices).
_Slippage_ occurs when a trade executes at a worse price than expected, typically due to insufficient liquidity. For instance, say an investor wants to buy 10 shares of tokenized AAPL (Apple) and that the ‘headline’ price of a share of an AAPL token is $230. That might seem fine, but that $230 price only indicates the lowest price at which another investor might be willing to sell a _single_ AAPL token; if the _next_ investor isn’t willing to sell their other nine AAPL tokens for less than $300 (which is their right), then _your_ cost to purchase ten shares might be (1\*$230 + 9\*$300) / 10 = $293 per token…a far cry from the “listed” $230 price. This is a direct causal effect: low liquidity causes high slippage by limiting the market's ability to absorb orders without volatility. In low-volume onchain markets, even small trades can amplify this, deterring participants and creating a feedback loop that further erodes liquidity.
_Price dislocations_, or mispricings, happen when the token's market price deviates from the underlying asset's fair value—such as a tokenized AAPL trading at a 15% premium over the underlying AAPL shares.
The cause of these dislocations is often a lack of _arbitrage_. Arbitrageurs normally correct dislocations by buying low and selling high. For example, let’s say that tokenized AAPL was trading on an exchange for $231, but was trading for $230 on another exchange. If there was a lot of liquidity — and if the transactions could happen quickly — an arbitrageur would simply buy the token for $230 on the one exchange and sell it for $231 on the other nearly instantly, and make a $1 profit with little risk. This type of dynamic happens in all kinds of financial markets and helps keeps prices consistent.
In many existing implementations of tokenized assets, however, high-friction minting and redemption processes (e.g., delays or costs in converting tokens back to underlying assets) prevent these type of quick interventions at low cost, and the low liquidity of the secondary markets (i.e. markets where the token is being traded directly, as opposed to the _primary_ market where they are being minted and burned) means that arbitrageurs can’t easily do it there, either.
So now you can see the issue: Low liquidity and high-friction minting and burning lead to high slippage, which signals market inefficiency and discourages arbitrage, allowing dislocations to widen and persist.
### So how do Ondo tokenized stocks address these issues?[](https://docs.ondo.finance/ondo-global-markets/comparison-to-other-tokenized-stocks#so-how-do-ondo-tokenized-stocks-address-these-issues)
Ondo tokenized stocks address these issues by enabling instant, low-cost minting/redemption and by inheriting liquidity from traditional markets. This allows arbitrageurs to align prices quickly and effectively, reducing token slippage and dislocations from day one.
### How else are Ondo tokenized stocks different?[](https://docs.ondo.finance/ondo-global-markets/comparison-to-other-tokenized-stocks#how-else-are-ondo-tokenized-stocks-different)
A few other key differences between Ondo tokenized stocks and some other tokenized stock implementations are that our assets are:
* Transferable 24/7
* Compatible with DeFi
* Structured to provide [strong investor protections](https://docs.ondo.finance/ondo-global-markets/trust-and-transparency)
Last updated on September 2, 2025
[Overview](https://docs.ondo.finance/ondo-global-markets/overview "Overview")
[Eligibility](https://docs.ondo.finance/ondo-global-markets/eligibility "Eligibility")
---
# Eligibility | Ondo Finance
[Ondo Global Markets](https://docs.ondo.finance/ondo-global-markets)
Eligibility
Eligibility
===========
This page provides information on the types of persons that are prohibited or restricted from subscribing for, acquiring or redeeming Ondo Global Markets tokens.
### Who is eligible to invest in Ondo tokenized stocks?[](https://docs.ondo.finance/ondo-global-markets/eligibility#who-is-eligible-to-invest-in-ondo-tokenized-stocks)
Ondo tokenized stocks are generally intended to be available to non-US investors, subject to certain jurisdictional and other restrictions. This page provides more information on the types of persons that are prohibited or restricted from subscribing for, acquiring or redeeming Ondo Global Markets tokens (i.e. Ondo tokenized stocks).
### Jurisdiction-Based Prohibitions:[](https://docs.ondo.finance/ondo-global-markets/eligibility#jurisdiction-based-prohibitions)
Individuals residing in or citizens of, and entities organized under the laws of or with a principal place of business in, any jurisdiction listed below (**“Prohibited Persons”**) are prohibited from subscribing for, acquiring or redeeming Ondo Global Markets tokens:
* Afghanistan
* Algeria
* Belarus
* Canada
* China (Does not include Hong Kong)
* Crimea, Donetsk People’s Republic (DNR), Luhansk People’s Republic (LNR), Kherson and Zaporizhzhia regions (Ukraine), the city of Sevastopol
* Cuba
* Democratic Republic of Korea
* Eritrea
* Iran
* Libya
* Myanmar
* Morocco
* Nepal
* Russia
* Somalia
* South Sudan
* Sudan
* Syria
* United States, or any of its states, possessions, territories or federal districts\*
* Venezuela
\*Persons who are located in, or place buy orders from within the United States, or any of its states, possessions, territories or federal districts, and persons who are “U.S. persons” or acting for the account or benefit of any “U.S. persons” within the meaning of Rule 902 of Regulation S promulgated under the United States Securities Act of 1933, as amended, are also prohibited from subscribing for, acquiring or redeeming Ondo Global Markets tokens.
Ondo Global Markets (BVI) Limited, the issuer of Ondo Global Markets tokens, also prohibits persons from subscribing for, acquiring or redeeming its tokens if it determines, in its sole discretion, that such activity may constitute a violation of (i) applicable laws, rules or regulations, including but not limited to sanctions restrictions, (ii) the terms of the Ondo Global Markets tokens’ governing documents; or (iii) the issuer’s governing documents and policies. In addition, if Prohibited Persons, directly or indirectly, hold in the aggregate 50% or more beneficial ownership or control of any entity, such entity may also be (or will be, if Prohibited Persons are prohibited as a result of applicable sanctions regulations) prohibited from subscribing for, acquiring or redeeming Ondo Global Markets tokens.
### Jurisdiction-Based Restrictions:[](https://docs.ondo.finance/ondo-global-markets/eligibility#jurisdiction-based-restrictions)
Individuals residing in or citizens of, and entities organized under the laws of or with a principal place of business in, any jurisdiction in the table set forth below must satisfy one or more of the eligibility requirements set forth opposite the name of such jurisdiction in order to be issued Ondo Global Markets tokens. For convenience purposes only, the below table also lists the key financial thresholds that are generally sufficient for an individual or entity to satisfy the applicable requirements; however, such information is provided only as a guide and does not amend, replace or supersede the requirements set forth under applicable laws, rules or regulations. Please refer to the applicable jurisdiction’s law, rules and regulations for definitions of the defined terms used in the table below. To onboard with the token issuer, Restricted Persons generally will be required to produce evidence that they satisfy the applicable eligibility requirements and to certify or declare their eligible status.
| Jurisdiction | Eligibility Requirements | Financial Thresholds (Individuals) | Financial Thresholds (Entities) |
| --- | --- | --- | --- |
| **Brazil** | “Qualified Investor” (CVM Resolution No. 30, Art. 12) | R$1M in financial investments; or approved technical qualification/certification | Professional investors; investment funds; or investment clubs (managed by Qualified Investors) |
| | “Professional Investor” (CVM Resolution No. 30, Art. 11) | R$10M in financial investments; or non-resident investor; or financial services accreditation (CVM) | Financial institutions; insurance/capitalization companies; pension entities; investment funds; or investment clubs (managed by CVM-authorized managers) |
| **Any Member State of the European Economic Area** | “Professional Client” (MiFID II, Annex II, Section I) or “Qualified Investor” (Prospectus Regulation (EU) 2017/1129) | EUR 500K financial portfolio; or 10 significant transactions per quarter over 4 quarters; or 1 year of financial sector experience | Regulated financial institutions; or large undertakings meeting 2 of: EUR 20M balance sheet, EUR 40M turnover, EUR 2M own funds |
| **Hong Kong** | “Professional Investor” (Individual) (PI Rules) | HK$8M portfolio value (alone or with associates) | Not applicable |
| | “Professional Investor” (Corporate/Trust) (PI Rules) | Not applicable | Trust corporations with HK$40M total assets; corporations/partnerships with HK$8M portfolio or HK$40M total assets; or investment holding companies owned by Professional Investors |
| | “Professional Investor” (Institutional) (SFO Schedule 1 Part 1) | Not applicable | Recognized exchange companies; intermediaries; financial institutions; insurers; investment schemes; governments; or central banks |
| **Malaysia** | “Sophisticated Investor” (High Net Worth Individual) (CMSA 2007) | RM 3M net personal/joint assets (excluding primary residence); or RM 300K income (individual) / RM 400K income (joint) | Not applicable |
| | “Sophisticated Investor” (High Net Worth Entity) (CMSA 2007) | Not applicable | Trust/public company trustees with RM 10M AUM; corporations or partnerships with RM 10M net assets; statutory bodies; or pension funds |
| | “Sophisticated Investor” (Accredited Investor) (CMSA 2007) | Not applicable | Unit trust schemes; CMSL holders; licensed banks; closed-end funds; or similar regulated entities |
| **Singapore** | “Accredited Investor” (SFA Section 4A(1)) | S$2M net personal assets (max S$1M from primary residence); or S$1M financial assets (net of liabilities); or S$300K annual income | S$10M net assets |
| | “Institutional Investor” (SFA Section 4A(1)(c)) | Not applicable | Governments; central banks; regulated financial institutions; pension funds; collective investment schemes; or similarly regulated institutions |
| **Switzerland** | FinSA “Professional Client” (Article 4(3)-(5)); or CISA “Qualified Investor” | Private investment structures for HNWIs with professional treasury ops; or HNWIs with >CHF 500K in assets and relevant knowledge; or >CHF 2M in assets regardless of experience | Regulated financial intermediaries; insurance companies; central banks; public entities; pension funds; companies with professional treasury ops; or large companies meeting 2 of: CHF 20M balance, CHF 40M turnover, CHF 2M equity |
| **United Kingdom** | “Professional Client” (MiFID II, Annex II, Section I); or “Qualified Investor” (Prospectus Regulation (EU) 2017/1129) | EUR 500K financial portfolio; or 10 significant transactions per quarter over 4 quarters; or 1 year of financial sector experience | Regulated financial institutions; or large undertakings meeting 2 of: EUR 20M balance sheet, EUR 40M turnover, EUR 2M own funds |
Please note that Ondo Global Markets (BVI) Limited also imposes non-jurisdiction-related eligibility criteria in accordance with its know-your-customer policies, procedures and practices and contractual agreements.
[Comparison to Other Tokenized Stocks](https://docs.ondo.finance/ondo-global-markets/comparison-to-other-tokenized-stocks "Comparison to Other Tokenized Stocks")
[Investing & Redeeming](https://docs.ondo.finance/ondo-global-markets/investing-and-redeeming "Investing & Redeeming")
---
# Investing & Redeeming | Ondo Finance
[Ondo Global Markets](https://docs.ondo.finance/ondo-global-markets)
Investing & Redeeming
Investing & Redeeming
=====================
Investing[](https://docs.ondo.finance/ondo-global-markets/investing-and-redeeming#investing)
---------------------------------------------------------------------------------------------
### What is the minimum I can invest or redeem?[](https://docs.ondo.finance/ondo-global-markets/investing-and-redeeming#what-is-the-minimum-i-can-invest-or-redeem)
The minimum is just $1.00 USD.
### Can I buy fractional tokens / shares?[](https://docs.ondo.finance/ondo-global-markets/investing-and-redeeming#can-i-buy-fractional-tokens--shares)
Yes, you can buy less than one full token. Please keep in mind, however, that Ondo tokenized stocks are total return tracker tokens, so a single token may, over time, provide exposure to more than one share of the underlying stock. [Learn more](https://docs.ondo.finance/ondo-global-markets/token-and-quote-pricing#how-is-the-price-of-an-ondo-tokenized-stock-determined)
### What forms of payment can I use to purchase Ondo tokenized stocks?[](https://docs.ondo.finance/ondo-global-markets/investing-and-redeeming#what-forms-of-payment-can-i-use-to-purchase-ondo-tokenized-stocks)
All Ondo tokenized stocks purchased from the Ondo Global Markets platform are purchased with [USDon](https://docs.ondo.finance/ondo-global-markets/available-assets#what-is-usdon)
, our native stablecoin. Thanks to the platform’s stablecoin swapper, however, USDC can be atomically converted 1:1 to USDon for mints, and USDon can be converted 1:1 to USDC automatically for redemptions.\*
This means that if you want to buy a tokenized stock with USDC, you can: in a single transaction, the USDC will be swapped for USDon, and the USDon will be used to purchase the tokenized stock, which is then sent to you.
\*Note that the ability to instantly swap USDC to/from USDon depends upon the stablecoin swapper having sufficient amounts of the other token available. For example, say you wanted to buy $100M worth of AAPLon with 100M USDC. If the swapper only had 50M USDon in it, you wouldn’t be able to do it. (If you already held 100M USDon in your wallet, however, you _would_ be able to.)
Also note that, even if there weren’t enough USDC in the swapper to redeem the entire amount to USDC, you can always redeem the entire amount to USDon and then swap USDon to USDC as the swapper is replenished. For example, say you had $100M worth of AAPLon that you wanted to redeem to USDC, but the swapper only contained 50M USDC. You could redeem the entire amount to USDon, swap 50M USDon for 50M USDC now, and then swap the remaining 50M USDon to USDC after the swapper is replenished. Because each USDon is backed by a dollar of cash or equivalents at a Global Markets brokerage account—and because 1 USDon is always swappable 1:1 for 1 USDC—once you redeem for USDon you are not exposed to further market risk.
Note that, by default, users are not whitelisted to swap between USDon and USDC; if you would like this ability, please contact us at [support@ondo.finance](mailto:support@ondo.finance)
. Please also note that the swapper does not currently have a UI; at this time, using it requires interacting directly with the smart contract.
### Can any type of wallet or account hold Ondo tokenized stocks?[](https://docs.ondo.finance/ondo-global-markets/investing-and-redeeming#can-any-type-of-wallet-or-account-hold-ondo-tokenized-stocks)
Ondo’s tokenized stocks are ERC20 compliant and transferable, so they can be held by any smart contracts or other externally owned accounts or wallets (e.g. Metamask, Bitget Wallet, Trust Wallet, OKX Wallet, etc.) In addition, certain custodians, including BitGo, Fireblocks, Zodia, and Ledger, also provide support. However, note that most centralized exchange custodial accounts (e.g. Binance, Coinbase) do not (yet).
### How long will it take for me to receive my Ondo tokenized stocks?[](https://docs.ondo.finance/ondo-global-markets/investing-and-redeeming#how-long-will-it-take-for-me-to-receive-my-ondo-tokenized-stocks)
The minting of new Ondo tokenized stocks is instant.
### How long will it take for me to receive my USDon?[](https://docs.ondo.finance/ondo-global-markets/investing-and-redeeming#how-long-will-it-take-for-me-to-receive-my-usdon)
If you wish to hold USDon in your wallet directly (as opposed to just atomically swapping USDC for USDon and then using USDon to purchase your tokenized stocks), you can still use our [stablecoin swapper](https://docs.ondo.finance/ondo-global-markets/investing-and-redeeming#what-forms-of-payment-can-i-use-to-purchase-ondo-tokenized-stocks)
to swap USDC for USDon and hold the USDon for later use. As noted [elsewhere](https://docs.ondo.finance/ondo-global-markets/investing-and-redeeming#what-forms-of-payment-can-i-use-to-purchase-ondo-tokenized-stocks)
, however, the ability to swap USDC for USDon instantly is dependent upon the amount of USDon available in the swapper. If you wish to obtain very large amounts of USDon (say $10M+) in very short order (i.e. within a day or two), please contact us at [support@ondo.finance](mailto:support@ondo.finance)
. Please note that the swapper does not currently have a UI; at this time, using it requires interacting directly with the smart contract.
### Are there offering documents like a prospectus, PPM, or loan documents I can see?[](https://docs.ondo.finance/ondo-global-markets/investing-and-redeeming#are-there-offering-documents-like-a-prospectus-ppm-or-loan-documents-i-can-see)
To comply with US laws and regulations, we are only able to provide such materials to investors who successfully complete our [onboarding process](https://docs.ondo.finance/ondo-global-markets/onboarding-and-kyc)
to prove [eligibility](https://docs.ondo.finance/ondo-global-markets/eligibility)
. You will have an opportunity to review all materials prior to investing.
### I want to invest via bank wire. How do I do that?[](https://docs.ondo.finance/ondo-global-markets/investing-and-redeeming#i-want-to-invest-via-bank-wire-how-do-i-do-that)
Purchasing Ondo tokenized stocks directly via bank wire is not currently supported. Purchasing USDon via bank wire is only available to those investing $500,000 or more.
Should you wish to do this, you will need to provide us with account information for the sending account. Include the account number, ABA/SWIFT Number, name of your bank, and the name on the account. You will also be given a specific code, which you will need to include in the memo/notes section of your wire. Finally, once the wire is sent, you will need to provide us with the unique identifier assigned by your bank to the transaction once the wire has been sent. Depending upon your bank, this might be called a MT103 Message, a UETR, or an IMAD. You will likely have to ask your bank to provide this to you. To begin this process, please contact us at [support@ondo.finance](mailto:support@ondo.finance)
.
Redeeming[](https://docs.ondo.finance/ondo-global-markets/investing-and-redeeming#redeeming)
---------------------------------------------------------------------------------------------
### What about redemptions?[](https://docs.ondo.finance/ondo-global-markets/investing-and-redeeming#what-about-redemptions)
Everything we mention above about investing applies to redemptions as well: you can redeem to USDon or USDC. The redemption to USDon will always be instant; redemptions to USDC will be instant provided there is enough liquidity in the stablecoin swapper. The minimum redemption amount to USDon or USDC is $1.00. Redemptions to USD via bank wire are not currently supported.
[Eligibility](https://docs.ondo.finance/ondo-global-markets/eligibility "Eligibility")
[Market Hours & Trading Availability](https://docs.ondo.finance/ondo-global-markets/market-hours-and-trading-availability "Market Hours & Trading Availability")
---
# Market Hours & Trading Availability | Ondo Finance
[Ondo Global Markets](https://docs.ondo.finance/ondo-global-markets)
Market Hours & Trading Availability
Market Hours & Trading Availability
===================================
### When is the Global Markets platform open for buying and selling?[](https://docs.ondo.finance/ondo-global-markets/market-hours-and-trading-availability#when-is-the-global-markets-platform-open-for-buying-and-selling)
The platform is generally available for trading from 8:05:00pm ET (New York time) Sunday evening through 7:59:00pm ET Friday evening whenever [US markets are open (opens in a new tab)](https://www.nyse.com/markets/hours-calendars)
. Specifically, trading is available during the following times:
* 4:00:00am ET - 9:29:00am ET (Pre-Market)
* 9:31:00am ET - 3:59:00pm ET (Core Session)
* 4:01:00pm ET - 7:59:00pm ET (Post-Market)
* 8:05:00pm ET - 3:55:00am ET (Overnight)
That said, there are some times when specific assets (and/or the platform generally) may not be available for trading. For example, there may be 1-5 minute pauses. Read the rest of this section to find out more. You can always check the exact status of what is and isn't trading on our status page, [status.ondo.finance (opens in a new tab)](https://status.ondo.finance/)
### Why are there small periods of time when trading is not available?[](https://docs.ondo.finance/ondo-global-markets/market-hours-and-trading-availability#why-are-there-small-periods-of-time-when-trading-is-not-available)
Tokens are generally available to trade during the same hours as the underlying assets trade on traditional exchanges. Stocks and ETFs that trade on the NYSE and NASDAQ typically trade during the following trading sessions:
* 4:00:00am ET - 9:29:59am ET (Pre-Market)
* 9:30:00am ET - 3:59:59pm ET (Core Trading Session)
* 4:00:00pm ET - 7:59:59pm ET (Post-Market)
In addition, over the past few years there has been growth in an overnight trading session that runs from 8:00:00pm - 3:59:59am ET (Overnight) that occurs on an Alternative Trading System (ATS) called Blue Ocean (we — like many other providers of 24/5 trading — leverage this platform to enable trading to occur 24 hours a day, 5 days a week.)
For platform and security reasons, we may temporarily halt trading a few minutes before and after a new session in the underlying trading venue begins.
### Does it make any difference to me during which trading session I buy or sell tokens via the platform?[](https://docs.ondo.finance/ondo-global-markets/market-hours-and-trading-availability#does-it-make-any-difference-to-me-during-which-trading-session-i-buy-or-sell-tokens-via-the-platform)
For most users, the answer is likely to be no. That said, there are some small caveats when trading during the overnight session:
* Because in general the liquidity in the overnight session is lower than during the other sessions, you may need to break larger orders into multiple smaller ones. In addition, the bid-ask spread can be wider, which can result in slightly worse pricing.
* Also because of this, the largest order / trade size you can place during the overnight session may be smaller than during the other sessions.
### Are all tokenized stocks always available to trade during market hours?[](https://docs.ondo.finance/ondo-global-markets/market-hours-and-trading-availability#are-all-tokenized-stocks-always-available-to-trade-during-market-hours)
In general, yes, but there are exceptions. See the next question.
### Under what conditions is trading halted?[](https://docs.ondo.finance/ondo-global-markets/market-hours-and-trading-availability#under-what-conditions-is-trading-halted)
**All Assets**
* Outside of [trading hours](https://docs.ondo.finance/ondo-global-markets/market-hours-and-trading-availability#when-is-the-global-markets-platform-open-for-buying-and-selling)
* On all [NYSE Market Holidays (opens in a new tab)](https://www.nyse.com/markets/hours-calendars)
* If certain proprietary platform-level risk control thresholds are met
* During scheduled or emergency platform maintenance
**Specific Assets**
* During corporate actions ([learn more](https://docs.ondo.finance/ondo-global-markets/corporate-actions)
)
* If certain proprietary asset-level risk control thresholds are met
* During scheduled or emergency asset-level maintenance
_Note: You can always check platform- and asset-level trading availability at [status.ondo.finance (opens in a new tab)](https://status.ondo.finance/)
_
[Investing & Redeeming](https://docs.ondo.finance/ondo-global-markets/investing-and-redeeming "Investing & Redeeming")
[Available Assets](https://docs.ondo.finance/ondo-global-markets/available-assets "Available Assets")
---
# Available Assets | Ondo Finance
[Ondo Global Markets](https://docs.ondo.finance/ondo-global-markets)
Available Assets
Available Assets
================
### What assets are available to trade through Ondo Global Markets?[](https://docs.ondo.finance/ondo-global-markets/available-assets#what-assets-are-available-to-trade-through-ondo-global-markets)
Investors can currently trade 100+ tokenized stocks and ETFs via the Global Markets platform, including the stock of popular companies (e.g. Tesla, Nvidia, Figma), indexes (e.g. QQQ, SPY), and fixed income ETFs (e.g. TLT, TIP, AGG). For a complete list, please visit our web app at [app.ondo.finance (opens in a new tab)](https://app.ondo.finance/)
.
### Do you just offer tokenized stocks? What about fixed income? ETFs? Mutual Funds?[](https://docs.ondo.finance/ondo-global-markets/available-assets#do-you-just-offer-tokenized-stocks-what-about-fixed-income-etfs-mutual-funds)
Yes, ETFs are available—when we say ‘tokenized stocks’ we intend to refer to the full set of available assets.
### What other stocks and ETFs do you intend to tokenize in the future?[](https://docs.ondo.finance/ondo-global-markets/available-assets#what-other-stocks-and-etfs-do-you-intend-to-tokenize-in-the-future)
The Ondo Global Markets platform was designed to be scalable quickly, and we intend to tokenize thousands of publicly traded assets over the coming months. Stay tuned.
### Do you only offer US stocks?[](https://docs.ondo.finance/ondo-global-markets/available-assets#do-you-only-offer-us-stocks)
We currently only offer tokenized versions of securities trading on the NYSE and NASDAQ exchanges. Over time, however, we may expand to tokenizing securities trading on exchanges in other countries.
### What is USDon?[](https://docs.ondo.finance/ondo-global-markets/available-assets#what-is-usdon)
USDon is a stablecoin backed 1:1 by a US dollar in one of Global Markets’ brokerage accounts. USDon is the stablecoin used to instantly buy or redeem Ondo tokenized stocks. When you purchase Ondo tokenized stocks with other stablecoins such as USDC, our platform [atomically swaps that stablecoin for USDon](https://docs.ondo.finance/ondo-global-markets/investing-and-redeeming#what-forms-of-payment-can-i-use-to-purchase-ondo-tokenized-stocks)
and then uses USDon to buy the tokenized stock. Similarly, when you sell your tokenized stock for USDC, our platform first redeems for USDon and then swaps that for USDC, all in one atomic transaction.
[Market Hours & Trading Availability](https://docs.ondo.finance/ondo-global-markets/market-hours-and-trading-availability "Market Hours & Trading Availability")
[Onboarding & KYC](https://docs.ondo.finance/ondo-global-markets/onboarding-and-kyc "Onboarding & KYC")
---
# Onboarding & KYC | Ondo Finance
[Ondo Global Markets](https://docs.ondo.finance/ondo-global-markets)
Onboarding & KYC
Onboarding & KYC
================
This section outlines how onboarding works today and what to expect as we continue rolling out improvements over the coming weeks.
Who can onboard today?[](https://docs.ondo.finance/ondo-global-markets/onboarding-and-kyc#who-can-onboard-today)
-----------------------------------------------------------------------------------------------------------------
At present, onboarding is open to **institutional participants** only.
Onboarding for **retail users/individuals** will be available directly through our web app in the near future.
What’s involved in onboarding?[](https://docs.ondo.finance/ondo-global-markets/onboarding-and-kyc#whats-involved-in-onboarding)
--------------------------------------------------------------------------------------------------------------------------------
The onboarding process can be broken down into four steps:
1. Joining the waitlist
2. KYC/KYB
3. Document signing
4. Account provisioning and approval
### **Joining the waitlist**[](https://docs.ondo.finance/ondo-global-markets/onboarding-and-kyc#joining-the-waitlist)
Join the waitlist to start the onboarding process:
1. Log into your [Ondo account (opens in a new tab)](https://ondo.finance/signin?destination=account)
2. Select **Onboarding** from the left-hand menu
3. Click **Join Waitlist** in the Ondo Global Markets information box
4. Follow the prompts to provide a few basic details and join the waitlist
After joining the waitlist, our onboarding team will contact you when it is your turn to start onboarding. Onboarding is currently only open to **institutional participants**, so they will be the first to be contacted to onboard, but retail users/individuals can also join the waitlist and will be contacted when the time comes to start their onboarding.
### **KYC/KYB**[](https://docs.ondo.finance/ondo-global-markets/onboarding-and-kyc#kyckyb)
When our onboarding team reaches out to you to start onboarding, they will provide you with a secure link to complete the KYB/KYC process via [Persona (opens in a new tab)](https://withpersona.com/)
, our identity and compliance partner. This process will guide you through:
* Identity verification
* Entity details (if applicable)
* Required documentation
When you reach the end of the KYB/KYC process in Persona, it will advise you that your information has been submitted for review. There is nothing more for you to do at this stage, as your application will now be reviewed by our team. We generally aim to review all materials within 3-4 Business Days. However, during periods of high demand we may take substantially longer. Either way, you will receive an email when your materials have been reviewed.
We are continuously improving this experience and will soon offer onboarding directly through our web app.
#### What information is required for KYC/KYB?[](https://docs.ondo.finance/ondo-global-markets/onboarding-and-kyc#what-information-is-required-for-kyckyb)
**Entities:**
* Legal name of entity
* Business name of entity (DBA or trading name if different)
* Country/territory of incorporation
* Addresses:
* Principal place of business
* Registered office address (if different)
* Mailing address (if different)
* Official identification number
* Wallet address(es)
**Individuals:**
* Legal name
* Birth date
* Country of citizenship and country of residence
* Addresses:
* Residential address
* Mailing address (if different)
* Tax ID number
* Wallet address(es)
Please note that the above lists are not exhaustive, and additional required information may be required during the KYC/KYB process.
After your application has been reviewed, additional information and/or documents may be required. When possible, we’ll send a single consolidated request for all additional materials.
#### What documents are required for onboarding?[](https://docs.ondo.finance/ondo-global-markets/onboarding-and-kyc#what-documents-are-required-for-onboarding)
**Entities:**
* Article of Existence Document Type (e.g. Certificate of Incorporation, Certificate of Formation, Certificate of Registration or licensing)
* Entity Proof of Address dated within the last 90 days
* correspondence from a central or local government department or agency
* bank statement
* utility bill
* lease or mortgage statement
* Entity Tax Self-Certification Form
* A link to this form is provided within the KYB flow
**Individuals:**
* Proof of address
* Government ID
After your application has been reviewed, additional information and/or documents may be required. When possible, we’ll send a single consolidated request for all additional materials.
### Signing Agreements[](https://docs.ondo.finance/ondo-global-markets/onboarding-and-kyc#signing-agreements)
After KYC/KYB has been approved, we will send the **Sales Terms** and **Subscription Form** for digital signing via trusted e-signature platform [HelloSign (opens in a new tab)](https://www.hellosign.com/)
(AKA Dropbox Sign). In the near future, this process will be even more seamless, with simple electronic agreement acceptance handled directly within the onboarding process.
Regardless of the format, we’ll ensure the signing process is clear and straightforward.
### Account provisioning and approval[](https://docs.ondo.finance/ondo-global-markets/onboarding-and-kyc#account-provisioning-and-approval)
Once KYC/KYB has been successfully completed and the required agreements have been signed, we will allowlist your wallet address(es) for GM tokens and approve your account.
### How can I receive assistance with the onboarding process?[](https://docs.ondo.finance/ondo-global-markets/onboarding-and-kyc#how-can-i-receive-assistance-with-the-onboarding-process)
**If you are currently in the process of onboarding** and have questions or require assistance, please contact us at [onboarding@ondo.finance](mailto:onboarding@ondo.finance)
, and our onboarding team will be happy to assist you.
**For general onboarding questions**, please contact us at [support@ondo.finance](mailto:support@ondo.finance)
.
[Available Assets](https://docs.ondo.finance/ondo-global-markets/available-assets "Available Assets")
[Transferability](https://docs.ondo.finance/ondo-global-markets/transferability "Transferability")
---
# Transferability | Ondo Finance
[Ondo Global Markets](https://docs.ondo.finance/ondo-global-markets)
Transferability
Transferability
===============
### Are Ondo stock tokens transferable?[](https://docs.ondo.finance/ondo-global-markets/transferability#are-ondo-stock-tokens-transferable)
Yes. All Ondo stocks are **transferable outside the US** across supported blockchains like [Ethereum (opens in a new tab)](https://ethereum.org/)
and [BNB Chain (opens in a new tab)](https://www.bnbchain.org/)
(with [Solana (opens in a new tab)](https://solana.com/)
and other chains coming soon), subject to [certain jurisdictional and other restrictions](https://docs.ondo.finance/ondo-global-markets/eligibility)
.
[Onboarding & KYC](https://docs.ondo.finance/ondo-global-markets/onboarding-and-kyc "Onboarding & KYC")
[Token & Quote Pricing](https://docs.ondo.finance/ondo-global-markets/token-and-quote-pricing "Token & Quote Pricing")
---
# Token & Quote Pricing | Ondo Finance
[Ondo Global Markets](https://docs.ondo.finance/ondo-global-markets)
Token & Quote Pricing
Token & Quote Pricing
=====================
### How is the price of an Ondo tokenized stock determined?[](https://docs.ondo.finance/ondo-global-markets/token-and-quote-pricing#how-is-the-price-of-an-ondo-tokenized-stock-determined)
Ondo tokenized stocks are designed to be _total-return trackers_ of their underlying securities. This means they reflect both price movements _and_ reinvested dividends and/or interest, giving users exposure to the economic performance of the real stock over time—not just the price appreciation.
When you hold an Ondo tokenized stock, you receive similar economic exposure to what you would get if you owned the actual underlying stock and invested its dividends (net of any applicable [withholding taxes](https://docs.ondo.finance/ondo-global-markets/fees-and-taxes#how-are-ondo-tokenized-stocks-taxed)
) into the stock. This ensures that the tokenized asset mirrors the total return of the real-world asset.
For more on how corporate actions are handled, read more [here](https://docs.ondo.finance/ondo-global-markets/corporate-actions)
.
### Can you give me an example?[](https://docs.ondo.finance/ondo-global-markets/token-and-quote-pricing#can-you-give-me-an-example)
Let’s take a sample stock, ACME, and its corresponding Ondo tokenized stock, ACMEon. At launch, assume they both start at $100 and that you buy one ACMEon token. If the ACME stock goes up by $5 to $105, the ACMEon stock should as well. Similarly, if the stock goes back down $100, the same should be true for the token.
Now let’s assume—again, for a simplified example—that ACME stock declares a dividend of $10 per share. On the ex-dividend date (i.e. the cutoff date on or after which whoever acquires the stock is no longer eligible to receive the dividend), we update the price of the token to account for the fact that we’re going to receive that dividend (net of applicable withholding taxes) and invest that money to purchase additional shares of ACME.
In this case, for ease of math let’s assume the withholding tax was 50%. This means that we’d receive $10\*(1-50%) = $5 from the dividend. If we assume the price of ACME at the time was still $100, that means we would buy $5/$100 = 0.05 additional shares of ACME stock. This means that, from now on (at least until the next dividend or corporate action), a single ACMEon token now actually represents the economics of 1.05 shares of ACME stock. Therefore, if the price of ACME stock was to go from $100 to $110 again, the price of the token would go from 1.05 shares \* $100/share = $105 to 1.05 \* $110/share = $115.50.
You can see this “shares per token” for each asset in our web app at [app.ondo.finance (opens in a new tab)](https://app.ondo.finance/)
\[_Technical Note:_ In the above example we assumed that the price of ACME stock on the ex-dividend date remained at $100. In reality if the dividend was $5, in most cases the price of the ACME stock would _drop_ by $5 to $95 on the ex-dividend date. (Why? Think about it: say someone offered you a stock for $100 today that would pay you $5 tomorrow. If they suddenly told you that you weren’t going to get the $5 tomorrow, wouldn’t you want to pay $5 less?). So the price of the stock is now $95. In our approach, our system effectively takes the $5 we expect from the dividend and buys $5/$95 = 0.05263158 more shares, so the number of shares backing each token goes from 1 to 1.05263158, so the price of the token remains at 1.05263158 \* $95 = $100. In other words, the price of the token remains the same, but the number of shares represented by each token increases.\]
### What is a total-return tracker?[](https://docs.ondo.finance/ondo-global-markets/token-and-quote-pricing#what-is-a-total-return-tracker)
Total-return trackers are financial assets that are designed to mirror the complete performance of an index or asset. Unlike _price_ return trackers, which only capture an asset’s market value changes, _total_ return trackers account for all cash flows—dividends, interest, or capital gains distributions—assuming these are reinvested to compound returns (net of applicable withholding taxes).
A total-return tracker includes:
* Price movements – gains or losses in the asset’s market value
* Income distributions – such as dividends (for stocks) or interest (for bonds)
* Corporate actions – like mergers that may affect total value ([learn more](https://docs.ondo.finance/ondo-global-markets/corporate-actions)
)
By capturing both capital gains and income, total-return trackers offer a more comprehensive reflection of an asset’s performance than price-only trackers.
### When I am actually buying or selling an Ondo tokenized stock, the price seems to be slightly different from the ‘main’ price listed? Why?[](https://docs.ondo.finance/ondo-global-markets/token-and-quote-pricing#when-i-am-actually-buying-or-selling-an-ondo-tokenized-stock-the-price-seems-to-be-slightly-different-from-the-main-price-listed-why)
Answering this requires a little bit more explanation about how our Global Markets platform works.
Let’s say you’re trying to buy Ondo tokenized Tesla, or TSLAon. What you really want to know is “at what price will you (the Global Markets platform) sell me (the investor) X number of TSLAon tokens?” As you might imagine, the answer to that is tied to a very similar question: “at what price will someone (in the traditional market) sell _us_ X number of TSLA _shares_?”
So when you indicate that you want to be X number of TSLAon tokens, we provide you a quote for a price that’s guaranteed for some amount of time (currently about 30 seconds). To generate that quote, the Global Markets platform automatically looks at existing inventory, market conditions, and other factors and then does a little bit of (proprietary) math to figure out what an appropriate quote price should be for that order.
Even on a traditional exchange, the _bid_ price (i.e. what someone is willing to pay to _b_uy a stock) is always lower than the _ask_ price (i.e. what someone is asking to receive if they sell a stock). \[Why? If someone was willing to pay $100 (the bid) for a stock and someone else was willing to sell for $99 (the ask), then the deal would have already been done!\]. The “main” price that is displayed is usually just the midpoint of those two numbers at the top of the order book.
For Ondo tokenized stocks, the “main” price you see for a given token is our estimate of that midpoint price of the underlying stock multiplied by the number of [shares per token](https://docs.ondo.finance/ondo-global-markets/token-and-quote-pricing#can-you-give-me-an-example)
, whereas the ‘quote price’ you receive when actually buying or selling tokens is the result of our proprietary method for determining at what price we can guarantee we can buy or sell that number of tokens. Those numbers should never be _too_ different from one another, but that’s where the discrepancy comes from.
(Please note that if you are buying an Ondo tokenized stock on the secondary market, whomever you are transacting with may be charging their own fees. You are also responsible for your own gas costs.)
### How do you determine the spread to apply on a quote?[](https://docs.ondo.finance/ondo-global-markets/token-and-quote-pricing#how-do-you-determine-the-spread-to-apply-on-a-quote)
This is based upon a number of factors, including quote size, target profit, and several other proprietary considerations.
[Transferability](https://docs.ondo.finance/ondo-global-markets/transferability "Transferability")
[Corporate Actions](https://docs.ondo.finance/ondo-global-markets/corporate-actions "Corporate Actions")
---
# Corporate Actions | Ondo Finance
[Ondo Global Markets](https://docs.ondo.finance/ondo-global-markets)
Corporate Actions
Corporate Actions
=================
### What is a corporate action?[](https://docs.ondo.finance/ondo-global-markets/corporate-actions#what-is-a-corporate-action)
A corporate action is any event initiated by a company that affects its securities—stocks, bonds, or other instruments—and typically requires updates to records, valuations, or entitlements for investors. Common examples of corporate actions are dividends, stock splits, mergers or acquisitions, spin-offs (creating a new, separate company and giving shares to existing holders), rights offerings (offering existing shareholders the chance to buy more shares at a discount), and (for bonds), bond calls or redemptions.
### How do corporate actions affect Ondo tokenized stocks?[](https://docs.ondo.finance/ondo-global-markets/corporate-actions#how-do-corporate-actions-affect-ondo-tokenized-stocks)
Each type of corporate action has different results. Continue reading for more detailed information.
### How are dividends handled?[](https://docs.ondo.finance/ondo-global-markets/corporate-actions#how-are-dividends-handled)
Dividends are automatically invested back into the referenced stock and reflected in token pricing. Minting and redemption quotes reflect both price changes and reinvested dividends. For a more detailed example, see the section about [how Ondo tokenized stocks are priced](https://docs.ondo.finance/ondo-global-markets/token-and-quote-pricing#can-you-give-me-an-example)
.
### Is trading halted during dividends?[](https://docs.ondo.finance/ondo-global-markets/corporate-actions#is-trading-halted-during-dividends)
Trading may be paused for a given stock or ETF for short time immediately before and after the start of the [ex-dividend date](https://docs.ondo.finance/ondo-global-markets/corporate-actions#what-is-an-ex-dividend-date)
. The exact duration of these pause may change over time as we try to shorten it, but for now you can assume trading may be paused 7:50:00pm-8:10:00pm the day before the dividend ex-date.
There is an exception to this rule, however. Unlike traditional stock dividends from individual companies, which are typically declared by the board of directors weeks or even months in advance with a fixed amount, ETF distributions (especially from fixed income funds) are often calculated based on the accrued income from underlying holdings like bonds, which can fluctuate due to interest payments, premium amortization, discount accretion, expenses, and other factors.
This means the exact distribution amount is frequently finalized and announced very close to the ex-date—often just 1-2 business days before, or even after hours on the day prior to the ex-date. As a result, the exact amount of this dividend may sometimes not appear in our data feeds for up to 24 hours.
In these cases, the platform _will_ halt trading until the exact amount of the dividend is known. Trading will resume as soon as the system can incorporate the dividend amount and appropriately increase the number of shares per token.
You can always check for upcoming dividends, as well as any tokens that are halted, at [status.ondo.finance (opens in a new tab)](https://status.ondo.finance/)
### What is an ‘ex-dividend’ date?[](https://docs.ondo.finance/ondo-global-markets/corporate-actions#what-is-an-ex-dividend-date)
When a company decides to pay a dividend (a portion of its profits) to its shareholders, it sets a few important dates to organize who gets the money. Two key dates are the **record date** and the **ex-dividend date** (or ex-date). These dates help decide who qualifies for the dividend.
1. **Record Date**: This is the day the company checks its list of shareholders to see who owns the stock and is eligible to receive the dividend. Think of it like the company taking a snapshot of its owners.
2. **Ex-Dividend Date (Ex-Date)**: This is the day when the stock starts trading _without_ the dividend included in its price. If you buy the stock on or after this date, you won’t get the upcoming dividend. If you buy it _before_ this date, you’re eligible for the dividend.
In the past, stock trades took two business days to "settle" (i.e. “trade + 2 days” or T+2), meaning it took two days for the buyer to officially become the owner of the stock. Because of this delay, the ex-date was set one day _before_ the record date to give the trade time to settle, ensuring the buyer was on the company’s list by the record date.
Now, with T+1 settlement, trades settle in just one business day. This means if you buy a stock the day before the record date, your purchase settles in time for you to be on the company’s list. As a result, the ex-date and record date are now the same day for most regular dividends.
As an example, imagine a company announces it will pay a $1 dividend. It sets:
* **Record Date**: July 10 (the day it checks who owns the stock).
* **Ex-Date**: Also July 10 (because of T+1 settlement)
Here’s how it works:
* If you buy the stock _before_ July 10 (say, on July 9 or earlier), your trade settles by July 10, so you’re on the company’s list and get the dividend.
* If you buy the stock _on or after_ July 10, you won’t get the dividend because you’re not the official owner until the next day (July 11), after the record date.
### What about other corporate actions?[](https://docs.ondo.finance/ondo-global-markets/corporate-actions#what-about-other-corporate-actions)
* Earnings: we may pause certain stocks around their earnings announcements, with the timing varying depending on the announcement time. For pre-market announcements, we may pause 5:00:00am-9:31:00am. For post-market announcements, we may pause 4:00:00pm-7:30:00pm. In the event that we pause we also may manually un-pause at any time during any of these windows, and may re-pause and un-pause multiple times in any of these windows.
More information about other corporate actions will be provided soon.
[Token & Quote Pricing](https://docs.ondo.finance/ondo-global-markets/token-and-quote-pricing "Token & Quote Pricing")
[Fees & Taxes](https://docs.ondo.finance/ondo-global-markets/fees-and-taxes "Fees & Taxes")
---
# Fees & Taxes | Ondo Finance
[Ondo Global Markets](https://docs.ondo.finance/ondo-global-markets)
Fees & Taxes
Fees & Taxes
============
### What fees does Global Markets charge?[](https://docs.ondo.finance/ondo-global-markets/fees-and-taxes#what-fees-does-global-markets-charge)
We do not charge any minting, redemption, or management fees on Ondo tokenized stocks. However, please note that when [a quote is generated](https://docs.ondo.finance/ondo-global-markets/token-and-quote-pricing#when-i-am-actually-buying-or-selling-an-ondo-tokenized-stock-the-price-seems-to-be-slightly-different-from-the-main-price-listed-why)
for an investor to buy (or sell) a token, the price may be slightly more (or less) than the price at which Ondo Global Markets buys (or sells) the underlying stock, with any difference being retained by Ondo Global Markets. Investors are responsible for their own gas costs.
(Note that if Ondo tokenized stocks are acquired in the secondary market, fees may be charged to you by other parties.)
### How are Ondo tokenized stocks taxed?[](https://docs.ondo.finance/ondo-global-markets/fees-and-taxes#how-are-ondo-tokenized-stocks-taxed)
Dividends or other income paid from underlying assets to Ondo Global Markets are subject to withholding taxes.
Withholding taxes are taxes that are automatically deducted from certain types of income—such as dividends—before that income is paid. For US stocks and bonds, brokers are generally required to withhold a portion of dividends payable to non‑U.S. investors based on the tax rules that apply to the entity receiving the dividend. The Ondo Global Markets entity that issues the tokens is based in the British Virgin Islands (BVI), so dividends paid by US securities to the entity are subject to the standard rates for BVI entities:
* For dividends from US-based companies, this rate is 30% in accordance with US tax regulations.
* For distributions from US-based fixed-income ETFs, this rate is also 30%, but certain portions of such distributions may be exempt from withholding tax (for example, income from US Treasury Bonds is considered exempt), so the effective rate may be less than 30%.
* For distributions from non-US companies listed as ADRs (e.g. though Spotify trades as SPOT on the NYSE, it is based in Sweden and the shares you buy on the NYSE represent underlying Luxembourg-listed ordinary shares), there is typically no US withholding tax, but Luxembourg will withhold 15% of the dividend before it even gets to the ADR, and then the ADR will pass on 100% of what’s left to the ADR holder).
The consequence of this is that the amount of any dividend reinvested in the underlying asset is net of any withholding tax (e.g. if AAPL paid out $1 in dividend, we’d only receive and reinvest $1 \* (1-30%) = $0.70.)
No other taxes (e.g., capital gains, income) are withheld for Ondo Global Markets, nor does Ondo Global Markets withhold any taxes when tokens are redeemed. However, investors may be subject to tax in connection with redeeming, purchasing or holding tokens, depending on the laws of the jurisdictions in which they are subject to tax, as well as their own particular tax circumstances. Each investor is solely responsible for understanding, reporting and fulfilling his, her, or its respective tax obligations. Ondo Global Markets strongly suggests that each investor consult his, her, or its own tax advisor to determine their tax obligations associated with redeeming, purchasing or holding Ondo Global Markets tokens.
[Corporate Actions](https://docs.ondo.finance/ondo-global-markets/corporate-actions "Corporate Actions")
[Technical](https://docs.ondo.finance/ondo-global-markets/technical "Technical")
---
# Technical | Ondo Finance
[Ondo Global Markets](https://docs.ondo.finance/ondo-global-markets)
Technical
Technical
=========
### On which chains is Global Markets available?[](https://docs.ondo.finance/ondo-global-markets/technical#on-which-chains-is-global-markets-available)
Global Markets is available on Ethereum mainnet and BNB Chain, with more chains coming soon.
### Are the Global Markets smart contracts audited?[](https://docs.ondo.finance/ondo-global-markets/technical#are-the-global-markets-smart-contracts-audited)
Yes. You can see the results of our audits [here](https://docs.ondo.finance/audits)
.
[Fees & Taxes](https://docs.ondo.finance/ondo-global-markets/fees-and-taxes "Fees & Taxes")
[Trust & Transparency](https://docs.ondo.finance/ondo-global-markets/trust-and-transparency "Trust & Transparency")
---
# Trust & Transparency | Ondo Finance
[Ondo Global Markets](https://docs.ondo.finance/ondo-global-markets)
Trust & Transparency
Trust & Transparency
====================
### How do I know my funds and assets are protected?[](https://docs.ondo.finance/ondo-global-markets/trust-and-transparency#how-do-i-know-my-funds-and-assets-are-protected)
_Bankruptcy-Remote Legal Structure_
Ondo tokenized stocks are issued using battle-tested practices designed to maximize bankruptcy remoteness. This includes issuance from a special purpose vehicle managed by a distinct Board of Directors with an independent director, as well as segregation of assets, books and accounts from Ondo Finance Inc. and the Ondo Foundation group. These measures help ensure that the tokens' backing assets remain protected, even in the unlikely event of a bankruptcy or insolvency.
_Full Asset Backing and Security Interest_
Ondo tokenized stocks are all fully backed by their underlying stocks and ETFs (together with cash in transit). Further, the issuer of Ondo tokenized stocks is required to ensure that there is additional collateral available—above and beyond this full backing—at all times to overcollateralize its obligations to tokenholders.
Tokenholder interests are further supported via an independent third-party security agent, Ankura Trust Company, which holds a first-priority, perfected security interest in this collateral, and is authorized and empowered to take possession of this collateral, exchange it for cash, and distribute the proceeds to tokenholders in specified events of issuer default. For example, if for some reason the issuer were unable to adequately service token redemption requests, or were unable to adequately maintain the full backing of the tokens, the requisite tokenholders could direct the security agent to take possession of this collateral, exchange it for cash, and distribute the proceeds to tokenholders as described above.
_Transparent Holdings with Regulated Custodians_
Ondo Global Markets provides daily attestations of Ondo tokenized stocks holdings, conducted by an independent third-party verification agent, Ankura Trust Company. The daily attestations can be viewed online beginning October 1, 2025. All Ondo Global Markets holdings are held with one or more U.S.-registered custodial broker-dealers.
_Smart Contract Security_
Ondo tokenized stock smart contracts have been rigorously tested and have undergone independent audits by Spearbit and Cyfrin to ensure code integrity and protocol safety. More details can be found [here](https://docs.ondo.finance/audits)
.
_Contractually Obligated Insurance Fund_
In addition to the above, the Ondo Foundation (via Flux Finance, Inc., a wholly owned subsidiary of the Ondo Foundation, which is the majority owner of the issuer of Ondo tokenized stocks) has guaranteed funds to further collateralize Ondo Global Markets' obligations to tokenholders.
### What kind of reporting will you provide?[](https://docs.ondo.finance/ondo-global-markets/trust-and-transparency#what-kind-of-reporting-will-you-provide)
Transparency is central to Global Markets:
* **Daily Reports:** We will publish daily updates on the holdings and net asset value (NAV) of the Global Markets product. These reports are independently reviewed by Ankura Trust for accuracy and completeness. Reports will begin being available within 60 days and can be found in the Token Holder Protections section of any Global Markets Asset Product Detail page, i.e. [https://app.ondo.finance/assets/nvdaon (opens in a new tab)](https://app.ondo.finance/assets/nvdaon)
* **Monthly Reconciliation:** Detailed reconciliation reports will be made public by the 20th of the following month, offering line-item clarity on holdings, fund flows, and account balances.
* **Annual Audits:** Full financial audits will be conducted annually by an independent audit firm and made available to investors.
### What happens if Ondo Finance files for bankruptcy?[](https://docs.ondo.finance/ondo-global-markets/trust-and-transparency#what-happens-if-ondo-finance-files-for-bankruptcy)
Ondo Finance, Inc. serves as the technology and service provider to the Global Markets issuer but is structurally and legally separate from the issuer entity. In the unlikely event that Ondo Finance enters bankruptcy, Global Markets’ structure is designed to prevent the issuer’s assets from being affected. The issuer is bankruptcy-remote, with independent governance, separate accounts, and third-party oversight to protect investors.
### What is the legal structure behind Global Markets?[](https://docs.ondo.finance/ondo-global-markets/trust-and-transparency#what-is-the-legal-structure-behind-global-markets)
Ondo Global Markets (BVI) Limited is a dedicated special purpose vehicle (SPV), a wholly separate legal entity from Ondo Finance Inc. and the Ondo Foundation group. This SPV:
* Is governed by a Board of Directors that includes an independent director.
* Maintains full segregation of assets, accounting, and operations from Ondo Finance and the Ondo Foundation group.
* Has engaged Ondo Finance solely as a service provider for tokenization and general and administrative operations.
### Who is the Ankura Trust Company?[](https://docs.ondo.finance/ondo-global-markets/trust-and-transparency#who-is-the-ankura-trust-company)
Ankura Trust Company serves as the Verification Agent and Security Agent for Global Markets. In these roles, Ankura:
* Reviews and verifies the existence and amounts of the underlying securities daily.
* Confirms reconciliation of investor liabilities and fund reserves.
* Holds a first-priority security interest in the underlying securities that serve as collateral for Ondo Global Markets' obligations to its tokenholders.
* Has legal authority to protect investor interests in the event of operational failure or insolvency, as defined by the governing control agreements.
[Technical](https://docs.ondo.finance/ondo-global-markets/technical "Technical")
[Legal & Regulatory](https://docs.ondo.finance/ondo-global-markets/legal-and-regulatory "Legal & Regulatory")
---
# Legal & Regulatory | Ondo Finance
[Ondo Global Markets](https://docs.ondo.finance/ondo-global-markets)
Legal & Regulatory
Legal & Regulatory
==================
### How are Ondo tokenized stocks structured legally?[](https://docs.ondo.finance/ondo-global-markets/legal-and-regulatory#how-are-ondo-tokenized-stocks-structured-legally)
An Ondo tokenized stock is a structured note: a debt instrument issued by Ondo Global Markets (BVI) Limited (known as the “Issuer”), a bankruptcy-remote special purpose vehicle (SPV) organized in the British Virgin Islands (BVI). Tokenholder rights and obligations are governed by Swiss law under the Issuer's Sales Terms. Ondo tokenized stocks are designed such that amount payable to the token (note) holder changes in value based upon the change in value of the corresponding underlying asset, including any corporate actions such as dividends, spin-offs, acquisitions, etc. These tokens are fully backed on a 1:1 basis (plus a [buffer](https://docs.ondo.finance/ondo-global-markets/trust-and-transparency#how-do-i-know-my-funds-and-assets-are-protected)
) by the corresponding underlying securities held via a regulated custodial broker-dealer (and cash in transit). The [Security Agent](https://docs.ondo.finance/ondo-global-markets/trust-and-transparency#who-is-the-ankura-trust-company)
holds a first-priority [security interest](https://docs.ondo.finance/ondo-global-markets/trust-and-transparency#how-do-i-know-my-funds-and-assets-are-protected)
in these underlying securities for the benefit of tokenholders.
### Does this mean the tokenholder does not actually own the underlying asset?[](https://docs.ondo.finance/ondo-global-markets/legal-and-regulatory#does-this-mean-the-tokenholder-does-not-actually-own-the-underlying-asset)
Ondo tokenized stocks are backed by specific assets that the Issuer holds through a regulated custodial broker-dealer, with safeguards in place to protect tokenholders’ claims. Like with brokerage accounts, you will not see your name on the share register for the underlying assets — they are held in the name of, or for the benefit of, the Issuer. In a traditional brokerage account, you might still be considered the beneficial owner with certain rights, such as receiving dividends, voting on corporate matters, and accessing shareholder communications. Ondo tokenized stocks are different: while you have the right to redeem your tokens for the then-value of the underlying assets, and while you benefit from a first-priority perfected [security interest](https://docs.ondo.finance/ondo-global-markets/trust-and-transparency#how-do-i-know-my-funds-and-assets-are-protected)
in those assets, you do not have shareholder voting rights, shareholder information rights or other shareholder rights from the issuer of the underlying securities.
Whether tokenholders might be considered the beneficial owner of the underlying assets for purposes such as reduced withholding tax rates depends on their particular situation and local laws, and they should consult their own tax advisor.
### How do you structure Ondo tokenized stocks and their offering to satisfy legal/compliance requirements?[](https://docs.ondo.finance/ondo-global-markets/legal-and-regulatory#how-do-you-structure-ondo-tokenized-stocks-and-their-offering-to-satisfy-legalcompliance-requirements)
Ondo Global Markets (BVI) Limited (“OGM”) structures its tokenized stock offerings to comply with applicable securities, AML/CFT, and other regulatory requirements in the jurisdictions in which it operates. OGM only offers and sells the tokens in reliance on the exemption provided by Regulation S under the U.S. Securities Act of 1933, as amended. To that end, OGM offers and sells the tokens only to persons who are (i) located outside the United States, (ii) not “US persons” as defined in Rule 902 of Regulation S, (iii) not acting for the account or benefit of any U.S. person, and (iv) not originating a buy order in the United States. Tokens may not be resold to any US person or into the United States unless pursuant to an effective registration statement or a valid exemption from registration and in compliance with the OGM Sales Terms (which you will receive a copy of once you successfully complete KYC onboarding).
OGM also imposes [jurisdictional and eligibility restrictions](https://docs.ondo.finance/ondo-global-markets/eligibility)
to comply with sanctions, anti-money laundering, counter financing of terrorism, securities and other laws in the United States and other jurisdictions. OGM also takes technical and operational measures to achieve compliance requirements and best practices. For example, persons who purchase tokens from OGM or redeem tokens to OGM must first successfully complete OGM’s onboarding process, which includes know-your-customer (KYC) review; and OGM employs technical tools for wallet and transaction screening.
### Who owns Ondo Global Markets (BVI) Limited?[](https://docs.ondo.finance/ondo-global-markets/legal-and-regulatory#who-owns-ondo-global-markets-bvi-limited)
Ondo Global Markets (BVI) Limited, the issuer of Ondo tokenized stocks, is 90.01% owned by Flux Finance Inc. (a wholly owned subsidiary of the Ondo Foundation) and 9.99% owned by Ondo Finance Inc.
[Trust & Transparency](https://docs.ondo.finance/ondo-global-markets/trust-and-transparency "Trust & Transparency")
[Partners & Media](https://docs.ondo.finance/ondo-global-markets/partners-and-media "Partners & Media")
---
# Partners & Media | Ondo Finance
[Ondo Global Markets](https://docs.ondo.finance/ondo-global-markets)
Partners & Media
Partners & Media
================
### My company is an asset manager for clients. Can we partner with you to offer Ondo tokenized stocks to our clients through our own platform?[](https://docs.ondo.finance/ondo-global-markets/partners-and-media#my-company-is-an-asset-manager-for-clients-can-we-partner-with-you-to-offer-ondo-tokenized-stocks-to-our-clients-through-our-own-platform)
Please contact us at [support@ondo.finance](mailto:support@ondo.finance)
.
### I want to reference Ondo in my tweet, blog post, or article. Do you have a logo or media kit I can use?[](https://docs.ondo.finance/ondo-global-markets/partners-and-media#i-want-to-reference-ondo-in-my-tweet-blog-post-or-article-do-you-have-a-logo-or-media-kit-i-can-use)
Yes, see our [Media Kit (opens in a new tab)](https://www.notion.so/Ondo-Media-Kit-3bc0a5aced014cc4b0ef62f1638bbf8e?pvs=21)
.
### I'd like to interview folks from Ondo. Who should I contact?[](https://docs.ondo.finance/ondo-global-markets/partners-and-media#id-like-to-interview-folks-from-ondo-who-should-i-contact)
Please contact us at [support@ondo.finance](mailto:support@ondo.finance)
.
[Legal & Regulatory](https://docs.ondo.finance/ondo-global-markets/legal-and-regulatory "Legal & Regulatory")
[Troubleshooting](https://docs.ondo.finance/ondo-global-markets/troubleshooting "Troubleshooting")
---
# Troubleshooting | Ondo Finance
[Ondo Global Markets](https://docs.ondo.finance/ondo-global-markets)
Troubleshooting
Troubleshooting
===============
### I’m trying to buy or sell a tokenized stock and it keeps failing. What should I do?[](https://docs.ondo.finance/ondo-global-markets/troubleshooting#im-trying-to-buy-or-sell-a-tokenized-stock-and-it-keeps-failing-what-should-i-do)
If you’re having trouble buying or selling Global Markets tokens, please first check [status.ondo.finance (opens in a new tab)](https://status.ondo.finance/)
to ensure that the platform is operating correctly, that markets are open, and that the token you are trying to buy or sell is currently trading. If you are still having issues, you can contact us at [support@ondo.finance](mailto:support@ondo.finance)
Our system also has certain risk parameters or rate limits. You may want to wait a few minutes and try again or try a smaller order size.
**Please note that we may only be able to support users trying to mint or redeem tokens via our API or web app directly.** If you are trying to buy or sell Ondo tokenized stocks on the secondary market, please contact the market directly.
### The price of my token doesn’t match the price of the underlying asset. Why not?[](https://docs.ondo.finance/ondo-global-markets/troubleshooting#the-price-of-my-token-doesnt-match-the-price-of-the-underlying-asset-why-not)
This is to be expected over time. Ondo Global Markets tokens are ‘total return’ trackers, so token prices will often not match the underlying asset. [Read more about this here](https://docs.ondo.finance/ondo-global-markets/token-and-quote-pricing#how-is-the-price-of-an-ondo-tokenized-stock-determined)
.
### When I am actually buying or selling an Ondo tokenized stock, the price seems to be slightly different from the ‘main’ price listed? Why?[](https://docs.ondo.finance/ondo-global-markets/troubleshooting#when-i-am-actually-buying-or-selling-an-ondo-tokenized-stock-the-price-seems-to-be-slightly-different-from-the-main-price-listed-why)
See [this](https://docs.ondo.finance/ondo-global-markets/token-and-quote-pricing#when-i-am-actually-buying-or-selling-an-ondo-tokenized-stock-the-price-seems-to-be-slightly-different-from-the-main-price-listed-why)
.
### I’m still having trouble. Who should I contact?[](https://docs.ondo.finance/ondo-global-markets/troubleshooting#im-still-having-trouble-who-should-i-contact)
If you are interacting directly via our API or web app, please contact us at [support@ondo.finance](mailto:support@ondo.finance)
. If you are transacting on the secondary market, please contact that party directly.
[Partners & Media](https://docs.ondo.finance/ondo-global-markets/partners-and-media "Partners & Media")
[Disclaimer](https://docs.ondo.finance/ondo-global-markets/disclaimer "Disclaimer")
---
# Disclaimer | Ondo Finance
[Ondo Global Markets](https://docs.ondo.finance/ondo-global-markets)
Disclaimer
Ondo Global Markets tokens (including Ondo tokenized stocks and Ondo tokenized ETFs) (the “Tokens”) have not been registered under the US Securities Act of 1933, as amended ("Act") or the securities or financial instrument laws of any other jurisdiction. The Tokens may not be offered or sold in the United States or to US persons unless registered under the Act or an exemption from the registration requirements thereof is available. In certain jurisdictions, including the European Economic Area, the United Kingdom and Switzerland, the Tokens are offered and sold only to qualified investors or professional clients, as the case may be (or that jurisdiction's analogue thereof). [Other jurisdiction-based prohibitions and restrictions apply](https://docs.ondo.finance/ondo-global-markets/eligibility)
. Ondo Global Markets (BVI) Limited, the issuer of Tokens, is not registered as an investment company under the US Investment Company Act of 1940, as amended, or as an Alternative Investment Fund or Undertaking for Collective Investment in Transferable Securities in the European Economic Area, or under the securities or financial instrument laws of any other jurisdiction. The Token-related communications herein are not directed or intended for any investor to which the Tokens are not offered.
Neither the Issuer nor the Tokens described herein have been registered with the British Virgin Islands Financial Services Commission (the “BVI FSC”) under the Securities and Investment Business Act (as revised) of the British Virgin Islands, the Virtual Assets Service Providers Act, 2022 of the British Virgin Islands or otherwise. Neither the BVI FSC, nor any other governmental authority in the British Virgin Islands or elsewhere, has passed judgment upon or approved the issuance of Tokens. There is no investment compensation scheme available in the British Virgin Islands. Tokens are not being, and may not be, offered to the public or to any person in the British Virgin Islands for purchase or subscription. Tokens may be offered to companies incorporated under the BVI Business Companies Act (as revised), but only where the offer is made to, and received by, the relevant BVI company entirely outside of the British Virgin Islands.
The Tokens provide their holders with economic exposure to the value of their underlying publicly traded assets, including the value of dividends (less applicable tax withholdings). However, the Tokens are not themselves stocks or ETFs, and they do not provide their holders with rights to hold or receive their respective underlying assets. Holders will not be entitled to receive dividends or vote as a shareholder or otherwise be deemed a shareholder of the Issuer for any purpose, nor shall holders have any right to vote for the election of directors or upon any matter submitted to the board of directors of the Issuer at any meeting thereof, or to give or withhold consent to any corporate action or to receive notice of or attend shareholder or board meetings, or to receive subscription rights or otherwise.
Neither the Ondo Global Markets (BVI) Limited offering documents for details (the “Offering Documents”), nor the ondo.finance website, nor any of its subdomains, nor any subpage of any of the foregoing, nor any terms or conditions set forth therein (collectively, the “GM Materials”) constitutes a prospectus (i) for the purposes of Article 3 of Regulation (EU) 2017/1129 of the European Parliament and Council of 14 June 2027 (the “Prospectus Regulation”) or (ii) within the meaning of Article 35 et seq. Of the Swiss Financial Services Act (“FinSA”) and have not been and will not be approved or reviewed by any Swiss regulatory authority or (iii) under a prospectus regulation of any other jurisdiction.
The GM Materials do not constitute an offer of, or a solicitation by or on behalf of, the Issuer to subscribe for or purchase any Tokens. The GM Materials are provided for informational purposes only. They do not constitute and are not construed as any advice, solicitation, offer, endorsement, commitment or recommendation to purchase or otherwise acquire any Tokens described therein. The provision of any GM Materials is not and shall not be a substitute for any persons’ own research, investigation, verification, checks or consultation for professional or investment advice. Each person who acquires Tokens is using the GM Materials at his, her or its own risk.
Additional terms and conditions apply. See, as applicable, [docs.ondo.finance/legal/terms-of-service](https://docs.ondo.finance/legal/terms-of-service)
, [docs.ondo.finance/ondo-global-markets](https://docs.ondo.finance/ondo-global-markets)
, [ondo.finance/global-markets (opens in a new tab)](https://ondo.finance/global-markets)
, and the Offering Documents.
[Troubleshooting](https://docs.ondo.finance/ondo-global-markets/troubleshooting "Troubleshooting")
[Secondary Market Restrictions](https://docs.ondo.finance/ondo-global-markets/secondary-market-restrictions "Secondary Market Restrictions")
---
# Ondo Chain | Ondo Finance
Ondo Chain
Ondo Chain
==========
[📄 Overview\
-----------\
\
An overview of Ondo Chain](https://docs.ondo.finance/ondo-chain/overview)
[🗃️ FAQ\
-------\
\
Frequently asked question about Ondo Chain](https://docs.ondo.finance/ondo-chain/faq)
[Secondary Market Restrictions](https://docs.ondo.finance/ondo-global-markets/secondary-market-restrictions "Secondary Market Restrictions")
[Overview](https://docs.ondo.finance/ondo-chain/overview "Overview")
---
# Special Terms Relating to the Acquisition of Tokens on the Secondary Market: | Ondo Finance
[Ondo Global Markets](https://docs.ondo.finance/ondo-global-markets)
Secondary Market Restrictions
Special Terms Relating to the Acquisition of Tokens on the Secondary Market:
============================================================================
Tokens may, in accordance with relevant applicable law, become listed on or acquired through one or more secondary markets. The Issuer does not guarantee that any secondary market exists or will exist for the Tokens, nor that such secondary markets will be available at any particular time. There is no guarantee that sufficient liquidity will be available to facilitate secondary markets in any particular Token. The Issuer also makes no representation as to the price of any Token on any secondary market; the price at which a Token may be issued at may not necessarily reflect the secondary market price of such Token. Each Token holder will assume and be solely responsible for all taxes of any jurisdiction related to their purchase, acquisition, sale or possession of any Tokens, and are advised to consult their tax advisors as to their specific consequences.
Each person who acquires Tokens on any secondary market will be deemed, by such acquisition, to have represented that: (a) they have received and acknowledged the disclaimers and warnings set out herein; (b) they understand the risks associated with each such disclaimer and warning; (c) that they are not then prohibited from acquiring Tokens, as described from time to time at [docs.ondo.finance/ondo-global-markets/eligibility](https://docs.ondo.finance/ondo-global-markets/eligibility)
(such prohibited persons, “Prohibited Persons”); (d) that the Tokens are suitable for them; and (e) that they wish to acquire Tokens issued by the Issuer.
For the avoidance of doubt, Prohibited Persons shall have no rights under any Offering Documents associated with the Tokens, and neither the Issuer, its respective directors, officers, employees, consultants, agents, representatives, shareholders, vendors or any third parties identified in the Offering Documents as being associated with any Tokens or Token offering, shall have any liability whatsoever to any Prohibited Persons.
As a condition to redeeming any of its Tokens, a Token holder must satisfy the Issuer’s customer due diligence, or “know your customer”, requirements. In the event of a redemption, the Issuer may refuse any redemption to a holder of any securities if the Issuer suspects or is advised that the redemption may be non-compliant with applicable laws, rules or regulations, or if such refusal is considered necessary or appropriate to ensure the compliance by the Issuer with any of its policies, procedures, practices or internal controls or any applicable laws, rules or regulations. Accordingly, there is a risk that a person acquiring Tokens on secondary markets will not meet such due diligence requirements and therefore may not be able to redeem any or all of its Tokens. Further, any delay, failure or violation could adversely affect the timing and number of payments by the Issuer to the holders of the securities.
Each person who acquires Tokens on the secondary market, by acquiring such Tokens, appoints Ankura Trust Company, LLC as the Security Agent. The Security Agent will hold the security interests in respect of any collateral related to the Tokens for the benefit of those parties possessing a security interest of the Issuer, and will be responsible for enforcing such security interests (as set forth in the Offering Documents) and causing payments to be made out of proceeds from any repossessed collateral in accordance with the Offering Documents.
Notices to acquirors of Tokens offered on blockchain platforms and other secondary markets will be published at [ondo.finance/global-markets (opens in a new tab)](https://ondo.finance/global-markets)
. They will only be published in the English language. It is presumed that notices published on the aforementioned website of the Issuer have been sufficiently brought to the attention and knowledge of secondary market acquirors of Tokens.
Consistent with with the Offering Documents, acquirors of Tokens on any secondary market acknowledge that the Issuer bears no liability whatsoever to holders of Tokens other than to carry out redemptions (for which “know your customer” diligence is a condition precedent) or as otherwise expressly set forth in the Sales Terms of the Issuer. Without limiting the foregoing the Issuer shall not have any responsibility to the extent permitted by law for any errors or omissions in the calculation of any amount or with respect to any other determination or decisions required to be made under any Offering Document or otherwise with respect to the Tokens. The Issuer shall not be liable for any extraordinary event outside of its direct control. Any such extraordinary event may reduce the redemption amount owed to Token holders, as determined by the Issuer. In no event shall the Issuer have any liability for indirect, incidental, consequential or other damages (even if it was advised of the possibility of such damages) other than interest until the date of payment on sums not paid when due in respect of any Tokens. Token holders are entitled to damages only (if any) and are not entitled to the remedy of specific performance in respect of any Token.
Consistent with the Offering Documents, to the fullest extent permitted by applicable laws, rules and regulations, any amounts due from the Issuer to any purchaser shall be equal to the lesser of the principal amount of the Issuer’s obligations under the Offering Documents and the actual amount received or recovered by or for the account of the Issuer in respect of any collateral relating to the Tokens, less any sums which the Issuer is or may be obligated to pay to any person in priority to such Purchaser. All payments to be made by the Issuer under the Offering Documents shall only be satisfied by recourse to the sums received or recovered by or on behalf of the Issuer in respect of any collateral relating to the Tokens. Purchasers shall have no further recourse to the Issuer. No purchaser of Tokens may institute against, or join any person in instituting against, the Issuer any bankruptcy, winding-up, examination, re-organisation, arrangement, insolvency or liquidation proceedings (except for as permitted pursuant to the terms of the Offering Documents) or other proceeding under any similar law for so long as any Tokens are outstanding or until one year plus one day has elapsed since the last day on which the Tokens were outstanding, without prejudice to any enforcement or realisation of the security interests in respect of any collateral relating to the Tokens, save lodging a claim in the liquidation of the Issuer which is initiated by another party or taking proceedings to obtain a declaration or judgment as to the obligations of the Issuer. No purchaser shall have any recourse to any director, officer or employee of the Issuer or any of its Affiliates or any of their respective assets.
Consistent with the Offering Documents, to the fullest extent permitted by applicable laws, purchasers of Tokens on any secondary market acknowledge that any dispute, controversy, or claim arising out of, or in relation to, the Tokens involving the Issuer (whether arising under contract law, tort law or otherwise), including without limitation regarding invalidity, breach, and/or termination thereof, and in relation with the Tokens, shall be resolved by arbitration in accordance with the Swiss Rules of International Arbitration of the Swiss Arbitration Centre in force on the date on which the “Note of Arbitration” is submitted as defined and in accordance with those rules. The number of arbitrations shall be one or three. The seat of the arbitration shall be Zurich, Switzerland. The arbitral proceedings shall be conducted in English.
[Disclaimer](https://docs.ondo.finance/ondo-global-markets/disclaimer "Disclaimer")
[Ondo Chain](https://docs.ondo.finance/ondo-chain "Ondo Chain")
---
# Ondo Chain Overview | Ondo Finance
[Ondo Chain](https://docs.ondo.finance/ondo-chain)
Overview
Ondo Chain Overview
===================
### Introduction[](https://docs.ondo.finance/ondo-chain/overview#introduction)
Ondo Chain\* is a Layer-1 blockchain purpose-built to accelerate the creation of institutional-grade financial markets onchain. By combining the openness of public blockchains with the compliance and security features of permissioned chains, Ondo Chain provides infrastructure to enable tokenized real-world assets to be used at scale.
### Key Features[](https://docs.ondo.finance/ondo-chain/overview#key-features)
* **Secured by High-Quality RWAs:** Validators can stake RWAs and other high quality liquid assets to secure the network, bridges, and oracles, reducing volatility risk and costs while enabling investors to earn additional yield on their RWAs.
* **Enshrined Oracles & Proof of Reserves:** Through consensus, validators will automatically verify key off-chain data such as asset prices (via price feeds) and proof of reserves (via custodians or broker dealers).
* **Native Omnichain Messaging & Bridging:** The Ondo decentralized verifier network (DVN) and multi-attestation protocols enable seamless cross-chain transactions to both EVM and non-EVM networks. Additional, third-party DVNs can be used at higher transaction amounts, balancing speed, cost, and safety. Ondo Chain also enables integrations into private, permissioned chains.
* **Permissioned Validators:** Validators will include institutional asset managers and broker-dealers and will be monitored to prevent front-running and support best execution, increasing investor protections.
* **Open Access & Development:** Virtually anyone can issue tokens, develop apps, or act as a user or investor.
* **RWA Focused Ecosystem:** Ondo Chain makes RWAs first-class citizens in DeFi, enabling borrowing, lending, staking, and cross-collateralization across traditional and crypto assets.
### Why Build Another L1?[](https://docs.ondo.finance/ondo-chain/overview#why-build-another-l1)
1. **Seamless, Cost-Effective Investor Experience**
Tightly coupling onchain and offchain infrastructure reduces costs, enhances security, and ensures low-latency operations for critical processes; these are important to ensure the type of user experience that institutional-grade financial markets require.
2. **Institutional Alignment**
A “public permissioned” model where financial institutions are involved in running the chain fosters security and compliance, ultimately giving these institutions more comfort about using the chain. As the goal is to bring financial markets onchain, having these institutions participate is critical because they hold the majority of the world’s investable assets and have access to traditional market liquidity with the best price execution for many assets.
3. **Unified Ecosystem**
Having a dedicated ecosystem built around RWAs allows for concentrated development of wallets, protocols, and applications tailored to the unique needs of financial markets. This unified focus fosters innovation, maximizes utility, and ensures that every participant in the ecosystem is aligned in advancing the use of tokenized assets.
### Applications Enabled by Ondo Chain[](https://docs.ondo.finance/ondo-chain/overview#applications-enabled-by-ondo-chain)
* **Prime Brokerage:** Access margin on both RWAs and crypto (including cross-collateralization) from both onchain and off-chain sources at competitive rates. Buy and sell from broker-dealers obligated to provide best execution, and receive competitive securities lending rates when you loan out your assets.
* **Staking and Collateral:** Stake [Ondo GM](https://docs.ondo.finance/ondo-global-markets/overview)
assets on Ondo Chain to enhance security, as well as post as collateral for borrowing and other uses.
* **Onchain Wealth Management:** Easily build and/or utilize onchain asset management strategies, including automatic 24/7 portfolio rebalancing across crypto, equities, ETFs and fixed income.
* **Cross-Chain Token Issuance:** Issue tokens that automatically work on multiple chains. Set conditions that must be met for bridges to take place. Manage and administer the assets seamlessly across chains.
* **Stablecoin Distribution and Yield:** Distribute stablecoins secured by tokenized securities and a variety of fixed income products across various supported blockchains and easily track minting and yield attribution.
* **Bootstrap Other Networks and Protocols:** Use restaked Ondo Chain RWAs to secure a new chain or protocol while the native token and network matures.
### Comparative Advantage[](https://docs.ondo.finance/ondo-chain/overview#comparative-advantage)
* **Compared to Public Chains:** Ondo Chain focuses on integrating liquid RWAs into DeFi, facilitates regulated institutional participation, and aids in security and investor protections through permissioned validators and exogenous asset staking.
* **Compared to Private Chains:** Ondo Chain provides open access, use, and development, enables the development of an open, robust DeFi ecosystem, and enables native bridging to other chains.
* **Compared to Bridging Protocols:** Ondo Chain is an L1 blockchain with its own state and logic, is secured by institutional participants and staked RWAs, and has integrations into traditional finance networks that enable lower cost and latency while enabling real time liquidity.
* * *
\*Ondo Chain and Ondo Global Markets (“GM”) have not launched. GM tokenized assets (“GM Assets”) will be backed by applicable securities; however, GM Assets and the underlying securities are distinct assets with their own respective performance and risk profiles. Upon launch, GM Assets will not be, and thereafter may not be, registered under the US Securities Act of 1933, as amended ("Act") or pursuant to securities laws of any other jurisdiction. GM Assets shall not be offered, sold or otherwise transferred in the US or to US persons unless registered under the Act or an exemption or exclusion from the registration requirements thereof is available. Upon launch, the issuers of GM Assets will not be, and thereafter may not be, registered as investment companies under the US Investment Company Act of 1940, as amended.
Providers of products, services or technologies on Ondo Chain (including but not limited to issuers of assets and providers of asset-related services) are responsible for their own products, services and technologies, including but not limited to the compliance of such products, services and technologies with applicable laws, rules and regulations. Ondo does not endorse, Ondo does not make any representation or warranty whatsoever (express or implied, including but not limited to any warranty of merchantability, fitness for a particular purpose or non-infringement) regarding, and ONDO SHALL NOT HAVE ANY LIABILITY WHATSOEVER WITH RESPECT TO ANYONE'S USE OF, any third-party products, services or technologies deployed to or accessible via Ondo Chain.
Nothing herein constitutes any offer to sell, or any solicitation of an offer to buy, any assets that may be deployed to or accessible via Ondo Chain (including but not limited to any GM Assets). Acquiring any such assets may (and for GM Assets will) involve risks. A holder of any such assets (including but not limited to any GM Assets) may incur losses, including total loss of their purchase price. Past performance may not be (and for GM Assets will not be) an indication of future results. Additional terms and conditions may (and for GM Assets will) apply.
[Ondo Chain](https://docs.ondo.finance/ondo-chain "Ondo Chain")
[FAQ](https://docs.ondo.finance/ondo-chain/faq "FAQ")
---
# Ondo Chain FAQ | Ondo Finance
[Ondo Chain](https://docs.ondo.finance/ondo-chain)
FAQ
Ondo Chain FAQ
==============
### What is Ondo Chain?[](https://docs.ondo.finance/ondo-chain/faq#what-is-ondo-chain)
Ondo Chain\* is a Layer 1 blockchain purpose-built to accelerate the creation of institutional-grade financial markets onchain. It combines the openness and accessibility of public blockchains with the security and compliance features required by institutional investors, enabling the seamless tokenization, trading, and use of real-world assets (RWAs) at scale.
### How does Ondo Chain compare to other solutions?[](https://docs.ondo.finance/ondo-chain/faq#how-does-ondo-chain-compare-to-other-solutions)
Ondo Chain builds on almost a decade of lessons from the industry regarding the use of blockchain technology in regulated financial applications. It combines elements of permissioned enterprise blockchains, public blockchains, L2 rollups, DeFi, bridging technology, and tokenized RWAs to create infrastructure to accelerate the development of institutional-grade financial markets onchain.
### Why does Ondo need its own chain?[](https://docs.ondo.finance/ondo-chain/faq#why-does-ondo-need-its-own-chain)
There are three reasons why we ultimately decided we needed to build our own L1 to bring financial markets onchain:
1. Tightly coupling onchain and offchain infrastructure reduces costs, enhances security, and ensures low-latency operations for critical processes; these are important to ensure the type of user-experience that institutional-grade financial markets require.
2. A “public permissioned” model where financial institutions are involved in running the chain fosters security and compliance, ultimately giving these institutions more comfort in using the chain. As the goal is to bring financial markets onchain, having these institutions participate is critical because they hold the majority of the world’s investable assets.
3. Having a dedicated ecosystem built around RWAs allows for concentrated development of wallets, protocols, and applications tailored to the unique needs of financial markets. This unified focus fosters innovation, maximizes utility, and ensures that every participant in the ecosystem is aligned in advancing the use of tokenized assets.
### How does Ondo Chain plan to compete with traditional financial infrastructure? [](https://docs.ondo.finance/ondo-chain/faq#how-does-ondo-chain-plan-to-compete-with-traditional-financial-infrastructure)
Ondo Chain provides the same institutional-grade benefits as traditional infrastructure, then supplements it with additional features enabled by blockchain technology, including global, 24/7/365 access, near-instant settlement, and open, easy asset issuance and distribution at lower cost. Just as importantly, Ondo Chain also enables tokenized assets to be used in DeFi-powered investment services at any time.
### What types of real-world assets will be supported at launch?[](https://docs.ondo.finance/ondo-chain/faq#what-types-of-real-world-assets-will-be-supported-at-launch)
At launch, [Ondo Global Markets](https://docs.ondo.finance/ondo-global-markets/overview)
(Ondo GM) will offer tokenized exposure to many of the most widely traded stocks such as Apple and Tesla, and a variety of popular bonds and ETFs from leading asset managers such Fidelity and BlackRock.
### How does Ondo Chain balance being permissioned for validators while remaining publicly accessible?[](https://docs.ondo.finance/ondo-chain/faq#how-does-ondo-chain-balance-being-permissioned-for-validators-while-remaining-publicly-accessible)
While validators are permissioned and limited to select institutions, the chain maintains an open architecture that allows anyone to issue tokens, develop applications, or participate as a user or investor. Developers retain the flexibility to implement their own permissioning and transfer restrictions at the smart contract level where needed.
### Why would developers want to build on Ondo Chain?[](https://docs.ondo.finance/ondo-chain/faq#why-would-developers-want-to-build-on-ondo-chain)
Beyond access to Ondo GM assets, Ondo Chain provides DeFi developers with seamless integration with traditional financial systems, built-in compliance tooling, and natively integrated cross-chain bridging, all as part of a familiar, EVM-compatible architecture. For developers wishing to build omnichain apps that utilize real-world assets, Ondo Chain will be the natural choice.
### What blockchains will Ondo Chain initially support for cross-chain operations? [](https://docs.ondo.finance/ondo-chain/faq#what-blockchains-will-ondo-chain-initially-support-for-cross-chain-operations)
Ondo Chain will include native bridging support for both EVM and non-EVM chains, including, but not limited to, Ethereum, Mantle, Arbitrum, Aptos, Sui, Solana, Plume, and the Cosmos Ecosystem, with the list continually expanding. Our goal is to ensure that Ondo Chain supports native bridging to every major public chain where RWAs will play a major role. In addition, Ondo Chain will also support connectivity into several major private, permissioned chains run by institutions, enabling access to previously inaccessible pools of liquidity.
### What's the timeline for Ondo Chain's launch and full implementation?[](https://docs.ondo.finance/ondo-chain/faq#whats-the-timeline-for-ondo-chains-launch-and-full-implementation)
At the time of writing, the technical design and testnet development are nearly completed and we are in conversations with institutional partners, including broker-dealers and distributors, to ensure we build a meaningful institutional ecosystem for Ondo Chain before launching mainnet.
### How do Ondo Chain and Ondo Global Markets work together?[](https://docs.ondo.finance/ondo-chain/faq#how-do-ondo-chain-and-ondo-global-markets-work-together)
[Ondo Global Markets](https://docs.ondo.finance/ondo-global-markets/overview)
and Ondo Chain are deeply interconnected components of a cohesive strategy to fundamentally upgrade capital markets. Ondo Global Markets enables the seamless tokenization of any publicly traded asset, while Ondo Chain is designed to provide the institutional-grade infrastructure to enable those assets and other RWAs to be used at scale. Together, they lay the foundations for a more inclusive and efficient financial system.
* * *
\*Ondo Chain and Ondo Global Markets (“GM”) have not launched. GM tokenized assets (“GM Assets”) will be backed by applicable securities; however, GM Assets and the underlying securities are distinct assets with their own respective performance and risk profiles. Upon launch, GM Assets will not be, and thereafter may not be, registered under the US Securities Act of 1933, as amended ("Act") or pursuant to securities laws of any other jurisdiction. GM Assets shall not be offered, sold or otherwise transferred in the US or to US persons unless registered under the Act or an exemption or exclusion from the registration requirements thereof is available. Upon launch, the issuers of GM Assets will not be, and thereafter may not be, registered as investment companies under the US Investment Company Act of 1940, as amended.
Providers of products, services or technologies on Ondo Chain (including but not limited to issuers of assets and providers of asset-related services) are responsible for their own products, services and technologies, including but not limited to the compliance of such products, services and technologies with applicable laws, rules and regulations. Ondo does not endorse, Ondo does not make any representation or warranty whatsoever (express or implied, including but not limited to any warranty of merchantability, fitness for a particular purpose or non-infringement) regarding, and ONDO SHALL NOT HAVE ANY LIABILITY WHATSOEVER WITH RESPECT TO ANYONE'S USE OF, any third-party products, services or technologies deployed to or accessible via Ondo Chain.
Nothing herein constitutes any offer to sell, or any solicitation of an offer to buy, any assets that may be deployed to or accessible via Ondo Chain (including but not limited to any GM Assets). Acquiring any such assets may (and for GM Assets will) involve risks. A holder of any such assets (including but not limited to any GM Assets) may incur losses, including total loss of their purchase price. Past performance may not be (and for GM Assets will not be) an indication of future results. Additional terms and conditions may (and for GM Assets will) apply.
[Overview](https://docs.ondo.finance/ondo-chain/overview "Overview")
[General-Access Products](https://docs.ondo.finance/general-access-products "General-Access Products")
---
# USDY Token | Ondo Finance
[General-Access Products](https://docs.ondo.finance/general-access-products)
USDY Token
USDY Token
==========
[📄 USDY Basics\
--------------\
\
What is USDY?](https://docs.ondo.finance/general-access-products/usdy/basics)
[📄 Comparison to Stablecoins\
----------------------------\
\
USDY is not classified as a traditional stablecoin; instead, it is a tokenized secured note. Like stablecoins, USDY...](https://docs.ondo.finance/general-access-products/usdy/comparison-stablecoins)
[📄 USDY vs Rebasing USDY (rUSDY)\
--------------------------------\
\
What's the difference between USDY and rUSDY?](https://docs.ondo.finance/general-access-products/usdy/usdy-vs-rebasing-usdy)
[📄 Rebasing\
-----------\
\
What is rebasing and how does it work?](https://docs.ondo.finance/general-access-products/usdy/rebasing)
[🗃️ FAQ\
-------\
\
There are three major processes for USDY](https://docs.ondo.finance/general-access-products/usdy/faq)
[📄 USDY Legal Disclaimer\
------------------------](https://docs.ondo.finance/general-access-products/usdy/disclaimer)
[General-Access Products](https://docs.ondo.finance/general-access-products "General-Access Products")
[USDY Basics](https://docs.ondo.finance/general-access-products/usdy/basics "USDY Basics")
---
# General-Access Products | Ondo Finance
General-Access Products
General-Access Products
=======================
[🗃️ USDY Token\
--------------\
\
6 items](https://docs.ondo.finance/general-access-products/usdy)
[FAQ](https://docs.ondo.finance/ondo-chain/faq "FAQ")
[USDY Token](https://docs.ondo.finance/general-access-products/usdy "USDY Token")
---
# USDY Basics | Ondo Finance
[General-Access Products](https://docs.ondo.finance/general-access-products)
[USDY Token](https://docs.ondo.finance/general-access-products/usdy)
USDY Basics
USDY Basics
===========
What is USDY?[](https://docs.ondo.finance/general-access-products/usdy/basics#what-is-usdy)
--------------------------------------------------------------------------------------------
USDY (**US** **D**ollar **Y**ield Token) is a tokenized note formerly issued by Ondo USDY LLC, which as of December 15, 2025 has been folded into the Ondo Global Markets umbrella. Depending on the issuance date, USDY may be secured by either short-term US Treasuries, shares of iShares Short Treasury Bond ETF, or bank demand deposits. USDY is accessible to qualifying non-US individual and institutional investors and is designed to combine the accessibility of a stablecoin with high-quality, US dollar-denominated yield.
USDY comes in two versions: an “accumulating” version (USDY) whose per-token price increases as yield accrues, and a “rebasing” version (rUSDY) whose price remains at US$1.00. Whereas the price of USDY tokens increases as the value of the underlying assets increase, with rUSDY you simply receive more rUSDY in your wallet; in effect the yield on the underlying assets accrues in the form of additional rUSDY tokens. For example, if you acquired 100 rUSDY tokens when the price per token of USDY was $1.00 – and then the price per token of USDY increased to US$1.01, the price per token of rUSDY would remain at $1.00, but your wallet would now hold 101 rUSDY tokens. This ‘rebasing’ happens automatically when the USDY price is updated each business day.
You can easily and instantly convert back and forth between USDY and rUSDY on our [website](https://docs.ondo.finance/general-access-products/usdy/usdy-vs-rebasing-usdy#how-do-i-convert-between-usdy-and-rusdy)
at any time.
| | USDY | rUSDY |
| --- | --- | --- |
| Token Type | Accumulating | Rebasing (distributing) |
| Yield Accrual Profile | Reflected through an increasing redemption price (Reference Token Price) | Reflected as a subdivision of rUSDY tokens into additional rUSDY tokens daily |
| As Treasury Yield Accrues, the Token Price | Increases | Remains at $1.00 |
| Best Suited for | Buy-and-hold cash management (some custodians only support accumulating tokens), collateral in smart contracts | Yield-bearing means of settlement or exchange |
How does it work?[](https://docs.ondo.finance/general-access-products/usdy/basics#how-does-it-work)
----------------------------------------------------------------------------------------------------
### I. Onboarding[](https://docs.ondo.finance/general-access-products/usdy/basics#i-onboarding)
To [onboard](https://docs.ondo.finance/general-access-products/usdy/faq/onboarding-and-kyc)
you must be eligible and complete our [Know Your Customer (KYC)](https://docs.ondo.finance/general-access-products/usdy/faq/onboarding-and-kyc)
process, provide us with the wallet address where you would like to receive your Tokens, and sign the [appropriate paperwork](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming)
.
### II. Investing[](https://docs.ondo.finance/general-access-products/usdy/basics#ii-investing)
Once your onboarding is completed, you will receive an email stating when you are eligible to invest. From then on, you can deposit USDC at any time. (For deposits of $100K plus, USD bank wires are also possible. Contact us for more information.) You will start [earning interest](https://docs.ondo.finance/general-access-products/usdy/faq/economics-and-fees)
as soon as your transaction is processed.
### Redeeming[](https://docs.ondo.finance/general-access-products/usdy/basics#redeeming)
Note that to comply with applicable US laws and regulations, Ondo USDY LLC can only redeem USD via bank wire to non-US bank accounts. If you wish to redeem via this method you will be required to provide us with such bank details before we can process a redemption request. Note that redemption for Temporary Global Certificates (i.e. prior to your token issuance) is only available for amounts greater than $100,000; for amounts less than this you will need to wait until your Tokens are minted. To redeem via API through Ondo Global Markets (BVI) Limited, please reach out to us at [support@ondo.finance](mailto:support@ondo.finance)
.
For more information on Ondo Global Markets (BVI) Limited see the [Ondo Global Markets section](https://docs.ondo.finance/ondo-global-markets)
of these docs. For more information on USDY issued through Ondo USDY LLC, or to learn how to redeem through Ondo USDY LLC, visit the [FAQ section](https://docs.ondo.finance/general-access-products/usdy/faq)
of these docs.
Understanding rUSDY[](https://docs.ondo.finance/general-access-products/usdy/basics#understanding-rusdy)
---------------------------------------------------------------------------------------------------------
**rUSDY = A Type of ‘Wrapped’ USDY**
It’s important to understand that each rUSDY still corresponds to some amount of “regular” USDY that is locked in a wrapper contract. This wrapper contract locks the USDY in the contract, mints the corresponding amount of rUSDY, and sends that rUSDY to your wallet. For example, if you had 1,000 USDY tokens worth $10 each — so, a total of $10,000 of value — the 1,000 USDY would be locked in the wrapper contract, which would then mint 10,000 rUSDY tokens and then send those to your wallet. Conversely, if you wanted to [convert](https://docs.ondo.finance/general-access-products/usdy/usdy-vs-rebasing-usdy#how-do-i-convert-between-usdy-and-rusdy)
your rUSDY tokens back to USDY tokens, your rUSDY tokens would be sent to the wrapper contract. This wrapper would then burn the rUSDY tokens, “unlock” the corresponding number of USDY tokens, and send those USDY tokens to your wallet.
This means that the _total_ supply of USDY is comprised of two ‘types’ of USDY:
* **Wrapped USDY** - i.e. USDY that is locked in the rUSDY wrapper contract and corresponds to the ‘reserve’ for the corresponding issued rUSDY.
* **Non-Wrapped USDY** — i.e. USDY that _isn’t_ locked in the rUSDY wrapper contract.
There are three important implications of this:
* The “dollar value” that is represented by all rUSDY tokens is exactly equal to the amount of “dollar value” represented by all applicable wrapped USDY tokens. In other words, `TVL_rUSDY = TVL_Wrapped_USDY` → `TVL_rUSDY = Num_Wrapped_USDY_Tokens * TokenReferencePrice_per_USDY` (Token Reference Price is the ‘face value’ of the token. You can learn more about how the price of USDY is determined [here](https://docs.ondo.finance/general-access-products/usdy/faq/economics-and-fees)
)
* Because of this, if you were to add up the total amount of USDY and the amount of rUSDY, you would be _double counting the value of the wrapped USDY_, because some of that value is already represented by the rUSDY.
* Therefore, to properly calculate the TVL of USDY, the appropriate calculation is as follows:
`Total USDY TVL (e.g. both versions) = Num_rUSDY_Tokens * $1.00 + Num_Non-Wrapped_USDY_Tokens * TokenReferencePrice_per_USDY`
OR
`Total USDY TVL (e.g. both versions) = (Num_Wrapped_USDY_Tokens + Num_Non-Wrapped_USDY_Tokens_ * TokenReferencePrice_per_USDY`
i.e. the two calculations should result in the same number (adjusting for rounding).
**rUSDY Price Stability via Rebasing**
Rebasing is a mechanism through which the total supply of tokens is adjusted. The basic intuition is that, if we’re trying to keep the price per token at $1.00, as the value of rUSDY’s underlying assets increase in value, we need to increase the number of tokens such that the “value of assets” divided by the number of tokens remains constant. For tokens like USDY and rUSDY, the redemption value of the rUSDY token can be calculated by dividing the TVL of the rUSDY share class by the number of rUSDY tokens
`TokenReferencePrice_per_rUSDY = TVL_rUSDY / Num_rUSDY_Tokens`
From above, recall that `TVL_rUSDY = Num_Wrapped_USDY_Tokens * TokenReferencePrice_per_USDY`, so we have `TokenReferencePrice_per_rUSDY = (Num_Wrapped_USDY_Tokens * TokenReferencePrice_per_USDY) / Num_rUSDY_Tokens` Therefore, as `TokenReferencePrice_per_USDY` increases each day based on the [Token yield rate](https://docs.ondo.finance/general-access-products/usdy/faq/economics-and-fees#how-is-the-price-of-usdy-determined)
for that month, `TokenReferencePrice_per_rUSDY` would _also_ increase…unless we also increased `Num_rUSDY_Tokens`. Since we want to keep `TokenReferencePrice_per_rUSDY` at $1.00, this means that we must increase `Num_rUSDY_Tokens` to keep the price at $1.00.
For more technical details on how rebasing works, you can read more [here](https://docs.ondo.finance/general-access-products/usdy/rebasing)
. For more detailed information about USDY, please refer to the rest of these support docs or reach out to us at [support@ondo.finance](mailto:support@ondo.finance)
* * *
**USDY Legal Disclaimer**
_USDY tokens have not been registered under the US Securities Act of 1933, as amended ("Act") or the securities or financial instrument laws of any other jurisdiction, and may not be offered or sold in the US or to US persons unless registered under the Act or an exemption from the registration requirements thereof is available. The Tokens are offered and sold in the European Economic Area and the United Kingdom solely to qualified investors, and in Switzerland solely to professional clients. Other jurisdiction-based prohibitions and restrictions apply. Ondo Global Markets (BVI) Limited, the issuer of USDY, is not registered as an investment company under the US Investment Company Act of 1940, as amended, or as an Alternative Investment Fund or Undertaking for Collective Investment in Transferable Securities in the European Economic Area, or under the securities or financial instrument laws of any other jurisdiction. Nothing herein constitutes any offer to sell, or any solicitation of an offer to buy, USDY. Nothing herein constitutes investing advice. Acquiring USDY involves risks. A USDY holder may incur losses, including total loss of their purchase price. Past performance is not an indication of future results. Additional terms apply. See [docs.ondo.finance/legal/terms-of-service](https://docs.ondo.finance/legal/terms-of-service)
, [docs.ondo.finance/general-access-products/usdy](https://docs.ondo.finance/general-access-products/usdy)
and [ondo.finance/usdy (opens in a new tab)](https://ondo.finance/usdy)
for details._
[USDY Token](https://docs.ondo.finance/general-access-products/usdy "USDY Token")
[Comparison to Stablecoins](https://docs.ondo.finance/general-access-products/usdy/comparison-stablecoins "Comparison to Stablecoins")
---
# Comparison to Stablecoins | Ondo Finance
[General-Access Products](https://docs.ondo.finance/general-access-products)
[USDY Token](https://docs.ondo.finance/general-access-products/usdy)
Comparison to Stablecoins
Comparison to Stablecoins
=========================
USDY is not classified as a traditional stablecoin; instead, it is a tokenized secured note. Like stablecoins, USDY operates as a bearer asset that can be transferred to investors without their needing to be onboarded with the issuer, although onboarding is necessary for minting or redeeming. However, unlike with stablecoins, USDY holders earn almost all of the yield from the assets that back USDY.
Below is a table that compares stablecoins and USDY:
| | Stablecoins | USDY |
| --- | --- | --- |
| Bankruptcy-remoteness | Stablecoins are generally issued out of operating companies. If a stablecoin issuer went bankrupt, including for reasons unrelated to operating their respective stablecoins, holders may be unable to redeem | USDY is issued by Ondo Global Markets (BVI) Limited, a company that is designed to be bankruptcy-remote from any other entities, including Ondo operating companies |
| Yield | Stablecoin holders receive no direct interest | USDY holders receive yield generated from the underlying assets (less amounts to satisfy fees, obligations, and expenses) in the form of increasing redemption value |
| Secured by high-quality assets | Stablecoins are generally unsecured liabilities of their issuers with no security interest in the assets that back them and are at risk of being subordinated to the claims of other creditors | USDY holders have a security interest in the assets that back it |
| Regulatory status | Stablecoins exist in a regulatory gray area and are not structured in a way to be able to pay holders a yield | USDY is issued in compliance with US federal and state securities and financial crime compliance laws |
| Third-party oversight | Stablecoin issuers can, in many cases, unilaterally change the type of assets that back them | Ankura Trust Company protects USDY holders as Verification Agent and Collateral Agent, enforcing narrow eligibility criteria and is able to force a wind-down in an event of non-compliance |
| Timely redemptions | If stablecoin issuers fail to meet redemption requests within a timely manner, there would be no Event of Default nor automatic wind-down process. Rather, stablecoin holders would likely need to litigate in court to recover their assets | If either Ondo USDY LLC (the previous issuer of USDY) or Ondo Global Markets (BVI) Limited fails to meet a redemption request in a timely manner, an Event of Default will occur, mandating Ankura Trust to liquidate the investment portfolio and repay token holders, subject to USDY holder approval |
* * *
**USDY Legal Disclaimer**
_USDY tokens have not been registered under the US Securities Act of 1933, as amended ("Act") or the securities or financial instrument laws of any other jurisdiction, and may not be offered or sold in the US or to US persons unless registered under the Act or an exemption from the registration requirements thereof is available. The Tokens are offered and sold in the European Economic Area and the United Kingdom solely to qualified investors, and in Switzerland solely to professional clients. Other jurisdiction-based prohibitions and restrictions apply. Ondo Global Markets (BVI) Limited, the issuer of USDY, is not registered as an investment company under the US Investment Company Act of 1940, as amended, or as an Alternative Investment Fund or Undertaking for Collective Investment in Transferable Securities in the European Economic Area, or under the securities or financial instrument laws of any other jurisdiction. Nothing herein constitutes any offer to sell, or any solicitation of an offer to buy, USDY. Nothing herein constitutes investing advice. Acquiring USDY involves risks. A USDY holder may incur losses, including total loss of their purchase price. Past performance is not an indication of future results. Additional terms apply. See [docs.ondo.finance/legal/terms-of-service](https://docs.ondo.finance/legal/terms-of-service)
, [docs.ondo.finance/general-access-products/usdy](https://docs.ondo.finance/general-access-products/usdy)
and [ondo.finance/usdy (opens in a new tab)](https://ondo.finance/usdy)
for details._
[USDY Basics](https://docs.ondo.finance/general-access-products/usdy/basics "USDY Basics")
[USDY vs Rebasing USDY (rUSDY)](https://docs.ondo.finance/general-access-products/usdy/usdy-vs-rebasing-usdy "USDY vs Rebasing USDY (rUSDY)")
---
# USDY vs Rebasing USDY (rUSDY) | Ondo Finance
[General-Access Products](https://docs.ondo.finance/general-access-products)
[USDY Token](https://docs.ondo.finance/general-access-products/usdy)
USDY vs Rebasing USDY (rUSDY)
USDY vs Rebasing USDY (rUSDY)
=============================
### **What’s the difference between USDY and rUSDY?**[](https://docs.ondo.finance/general-access-products/usdy/usdy-vs-rebasing-usdy#whats-the-difference-between-usdy-and-rusdy)
The ‘r’ in rUSDY stands for ‘rebasing’. rUSDY is intended to maintain a price of $1.00 per token (with the accruing yield being represented by the division of rUSDY tokens into more tokens via [rebasing](https://docs.ondo.finance/general-access-products/usdy/rebasing)
). By contrast, the accruing yield of USDY tokens gets ‘accumulated’ into the price, such that the price of USDY is intended to appreciate over time. For example, let’s say you held 100 rUSDY tokens and 100 USDY tokens that were each worth a dollar. The next day the USDY price per token increased to $1.01 per token. After the price update and rebasing, your holdings of both rUSDY and USDY would each be worth $101.00. You would still have a balance of 100 USDY tokens worth $1.01 apiece. However, due to the rebasing nature of rUSDY tokens, you would now hold 101 rUSDY tokens worth $1.00 per token.
### **How do I decide between USDY and rUSDY?**[](https://docs.ondo.finance/general-access-products/usdy/usdy-vs-rebasing-usdy#how-do-i-decide-between-usdy-and-rusdy)
While we believe many tokenholders will want to hold rUSDY because of its intended price stability, certain protocols, exchanges, or custodians may not support rebasing tokens. Regardless, converting between USDY and rUSDY is [easy](https://docs.ondo.finance/general-access-products/usdy/usdy-vs-rebasing-usdy#how-do-i-convert-between-usdy-and-rusdy)
.
### **How do I convert between USDY and rUSDY?**[](https://docs.ondo.finance/general-access-products/usdy/usdy-vs-rebasing-usdy#how-do-i-convert-between-usdy-and-rusdy)
Use the [Ondo Converter (opens in a new tab)](https://ondo.finance/convert)
on our website to easily convert between USDY and rUSDY.
* * *
**USDY Legal Disclaimer**
_USDY tokens have not been registered under the US Securities Act of 1933, as amended ("Act") or the securities or financial instrument laws of any other jurisdiction, and may not be offered or sold in the US or to US persons unless registered under the Act or an exemption from the registration requirements thereof is available. The Tokens are offered and sold in the European Economic Area and the United Kingdom solely to qualified investors, and in Switzerland solely to professional clients. Other jurisdiction-based prohibitions and restrictions apply. Ondo Global Markets (BVI) Limited, the issuer of USDY, is not registered as an investment company under the US Investment Company Act of 1940, as amended, or as an Alternative Investment Fund or Undertaking for Collective Investment in Transferable Securities in the European Economic Area, or under the securities or financial instrument laws of any other jurisdiction. Nothing herein constitutes any offer to sell, or any solicitation of an offer to buy, USDY. Nothing herein constitutes investing advice. Acquiring USDY involves risks. A USDY holder may incur losses, including total loss of their purchase price. Past performance is not an indication of future results. Additional terms apply. See [docs.ondo.finance/legal/terms-of-service](https://docs.ondo.finance/legal/terms-of-service)
, [docs.ondo.finance/general-access-products/usdy](https://docs.ondo.finance/general-access-products/usdy)
and [ondo.finance/usdy (opens in a new tab)](https://ondo.finance/usdy)
for details._
[How It Works](https://docs.ondo.finance/general-access-products/usdy/how-it-works "How It Works")
[Rebasing](https://docs.ondo.finance/general-access-products/usdy/rebasing "Rebasing")
---
# Rebasing | Ondo Finance
[General-Access Products](https://docs.ondo.finance/general-access-products)
[USDY Token](https://docs.ondo.finance/general-access-products/usdy)
Rebasing
Rebasing
========
### **What is rebasing and how does it work? How is it different than airdropping?**[](https://docs.ondo.finance/general-access-products/usdy/rebasing#what-is-rebasing-and-how-does-it-work-how-is-it-different-than-airdropping)
Rebasing is a mechanism through which the total supply of tokens is adjusted. Rebasing works by taking the “base” number of tokens, T, and multiplying it by some “rebasing factor”, RF, to get a new number of tokens. For example, let’s say there were a total of 100 tokens: 10 were held by Holder A (10% of the total) and 90 by Holder B (90% of the total). In a rebasing, we might want to double the total number of tokens (i.e. a rebasing factor of 2). We multiply each holder’s balance by the Rebasing Factor — 2 in this case — so after rebasing a total of 200 tokens are outstanding in which Holder A has 20 tokens (still 10% of the total) and Holder B has 180 tokens (still 90% of the total). Economically, Holder A and Holder B are in the same position both before and after rebasing. How can we do this? One way would be to mint and airdrop new tokens to each token holder. This would cost a lot of gas, however, because it requires updating each token contract storage location that represents a user’s balance. Rebasing allows us to adjust all token holder balances in a gas-efficient manner by introducing the concept of user “shares”. A “share” is similar to a share of a company’s stock - it can be thought of as a claim on a percentage of the total supply of rUSDY tokens (and, in fact, the concept of rebasing is similar to the concept of a share split – except rebasing is automatic). A user’s balance is then equal to the percentage of total shares they hold, multiplied by the total number of shares:
`NumTokens_User = NumTokens_Total * (NumShares_User / NumShares_Total)`
When we rebase, therefore, we only have to update **_one_** contract storage location: `NumTokens_Total`. As you can see from the formula above, that will increase the balance in your wallet while keeping your **_percentage_** of the total tokens the same. Here’s an example where we increase `NumTokens_Total` from 100 to 200:
| | Holder A Shares | Holder B Shares | Total Number of Shares | Total Supply of rUSDY Tokens | Holder A rUSDY Balance | Holder B rUSDY Balance |
| --- | --- | --- | --- | --- | --- | --- |
| Before Rebasing | 1 | 9 | 10 | 100 | (1/10) \* 100 = 10 rUSDY Tokens | 9/10\* 100 = 90 rUSDY Tokens |
| After Rebasing | 1 | 9 | 10 | 200 (increase) | (1/10) \* 200 = 20 rUSDY Tokens | 9/10 \* 200 = 180 rUSDY Tokens |
And what number do we set the `NumTokens_Total` to be? We set it equal to the Total Value Locked (TVL) of rUSDY as of the latest price update. In other words, we set `NumTokens_Total = TVL`, thereby making `TVL / NumTokens_Total equal` to $1.00.
The rebasing factor RF, then, is calculated as `RF = NumTokens_Total_New / NumTokens_Total_Old`.
We can use a simple example to check this. Let’s say that on Monday the total number of tokens after rebase (NumTokens\_Total\_Old) was 2 (implying an rUSDY TVL of $2.00). Let’s also say that at the end of Monday, the price of USDY increased to $2, so the TVL of rUSDY at the end of the day (TVL) was now $4. This implies that the Reference Token Price - the ‘face value’ of the rUSDY token price - is 4 dollars / 2 tokens = $2 per token. To make the Reference Token price per rUSDY token equal to $1.00 after rebase on Tuesday, we need to double the number of tokens. In this case, the RF would be 2 ($4/$2 = 2). As a result, because the number of rUSDY tokens doubled for everyone, the Reference Token Price per rUSDY token would be reduced to $1.00 per token.
Finally, please note that when your rUSDY balance increases due to rebasing, you will see the balance increase in your wallet, but you will not see an accompanying transaction in your wallet’s activity or on a block explorer. This is because the tokens are simply being rebased rather than tokens being sent to the holder’s wallet.
### **How often do you rebase rUSDY?**[](https://docs.ondo.finance/general-access-products/usdy/rebasing#how-often-do-you-rebase-rusdy)
rUSDY is rebased daily at the same time the USDY price is updated. You can learn more about how the price of USDY is determined [here](https://docs.ondo.finance/general-access-products/usdy/faq/economics-and-fees#how-is-the-price-of-usdy-determined)
.
Yield is accrued to tokens at the time of the respective price update. As a result, holders of both rUSDY and USDY who submit a redemption request prior to the daily price update (and corresponding rebase) on a given day do not accrue yield on those tokens for that day. Please note that rUSDY and USDY holders are not ‘paid out’ yield, but rather that yield is reflected by the increased value of their existing USDY tokens or increased number of rUSDY tokens.
### **What is the difference between rebasing rUSDY and updating the USDY token price onchain?**[](https://docs.ondo.finance/general-access-products/usdy/rebasing#what-is-the-difference-between-rebasing-rusdy-and-updating-the-usdy-token-price-onchain)
When the USDY token price (aka the Reference Token Price) is updated each day, a rebase occurs in the same block, so you can think of a “price update” and a “rebase” as de facto being the same events, occuring at the same time.
### **How do I convert between USDY and rUSDY?**[](https://docs.ondo.finance/general-access-products/usdy/rebasing#how-do-i-convert-between-usdy-and-rusdy)
Use the [Ondo Converter (opens in a new tab)](https://ondo.finance/convert)
on our website to easily convert between USDY and rUSDY
* * *
**USDY Legal Disclaimer**
_USDY tokens have not been registered under the US Securities Act of 1933, as amended ("Act") or the securities or financial instrument laws of any other jurisdiction, and may not be offered or sold in the US or to US persons unless registered under the Act or an exemption from the registration requirements thereof is available. The Tokens are offered and sold in the European Economic Area and the United Kingdom solely to qualified investors, and in Switzerland solely to professional clients. Other jurisdiction-based prohibitions and restrictions apply. Ondo Global Markets (BVI) Limited, the issuer of USDY, is not registered as an investment company under the US Investment Company Act of 1940, as amended, or as an Alternative Investment Fund or Undertaking for Collective Investment in Transferable Securities in the European Economic Area, or under the securities or financial instrument laws of any other jurisdiction. Nothing herein constitutes any offer to sell, or any solicitation of an offer to buy, USDY. Nothing herein constitutes investing advice. Acquiring USDY involves risks. A USDY holder may incur losses, including total loss of their purchase price. Past performance is not an indication of future results. Additional terms apply. See [docs.ondo.finance/legal/terms-of-service](https://docs.ondo.finance/legal/terms-of-service)
, [docs.ondo.finance/general-access-products/usdy](https://docs.ondo.finance/general-access-products/usdy)
and [ondo.finance/usdy (opens in a new tab)](https://ondo.finance/usdy)
for details._
[USDY vs Rebasing USDY (rUSDY)](https://docs.ondo.finance/general-access-products/usdy/usdy-vs-rebasing-usdy "USDY vs Rebasing USDY (rUSDY)")
[FAQ](https://docs.ondo.finance/general-access-products/usdy/faq "FAQ")
---
# Faq | Ondo Finance
[General-Access Products](https://docs.ondo.finance/general-access-products)
[USDY Token](https://docs.ondo.finance/general-access-products/usdy)
FAQ
[📄 Eligibility\
--------------\
\
Who can invest in USDY? Who can redeem? Who can trade it?](https://docs.ondo.finance/general-access-products/usdy/faq/eligibility)
[📄 Onboarding & KYC\
-------------------\
\
What's involved in onboarding and KYC?](https://docs.ondo.finance/general-access-products/usdy/faq/onboarding-and-kyc)
[📄 USDYc\
--------\
\
What is USDYc?](https://docs.ondo.finance/general-access-products/usdy/faq/usdyc)
[📄 Investing & Redeeming\
------------------------\
\
Investing and redeeming](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming)
[📄 Transfers\
------------\
\
Can I transfer the Tokens?](https://docs.ondo.finance/general-access-products/usdy/faq/transfers)
[📄 Economics & Fees\
-------------------\
\
How quickly after investing do I start earning yield?](https://docs.ondo.finance/general-access-products/usdy/faq/economics-and-fees)
[📄 Trust & Transparency\
-----------------------\
\
How do I know my funds are safe / protected?](https://docs.ondo.finance/general-access-products/usdy/faq/trust-and-transparency)
[📄 Technology\
-------------\
\
Where can I view Ondo smart contracts and addresses?](https://docs.ondo.finance/general-access-products/usdy/faq/technology)
[📄 Partners & Media\
-------------------\
\
My company is an asset manager for clients. Can we partner with you to offer your USDY to our clients through our own platform](https://docs.ondo.finance/general-access-products/usdy/faq/technology)
[Rebasing](https://docs.ondo.finance/general-access-products/usdy/rebasing "Rebasing")
[Eligibility](https://docs.ondo.finance/general-access-products/usdy/faq/eligibility "Eligibility")
---
# Ondo USDY LLC | Ondo Finance
[General-Access Products](https://docs.ondo.finance/general-access-products)
[USDY Token](https://docs.ondo.finance/general-access-products/usdy)
[FAQ](https://docs.ondo.finance/general-access-products/usdy/faq)
Eligibility
Ondo USDY LLC
=============
Tokenholder Eligibility Criteria
================================
This page provides information on the types of persons that are prohibited or restricted from subscribing for, acquiring or redeeming USDY tokens.
Jurisdiction-Based Prohibitions:[](https://docs.ondo.finance/general-access-products/usdy/faq/eligibility#jurisdiction-based-prohibitions)
-------------------------------------------------------------------------------------------------------------------------------------------
Individuals residing in or citizens of, and entities organized under the laws of or with a principal place of business in, any jurisdiction listed below (**“Prohibited Persons”**) are prohibited from subscribing for, acquiring or redeeming USDY tokens:
* Afghanistan
* Algeria
* Belarus
* Canada
* China (Does not include Hong Kong)
* Crimea, Donetsk People’s Republic (DNR), Luhansk People’s Republic (LNR), Kherson and Zaporizhzhia regions (Ukraine), the city of Sevastopol
* Cuba
* Democratic Republic of Korea
* Eritrea
* Iran
* Libya
* Myanmar
* Morocco
* Nepal
* Russia
* Somalia
* South Sudan
* Sudan
* Syria
* United States, or any of its states, possessions, territories or federal districts\*
* Venezuela
\*Persons who are located in, or place buy orders from within the United States, or any of its states, possessions, territories or federal districts, and persons who are “U.S. persons” or acting for the account or benefit of any “U.S. persons” within the meaning of Rule 902 of Regulation S promulgated under the United States Securities Act of 1933, as amended, are also prohibited from subscribing for, acquiring or redeeming USDY tokens.
Ondo USDY LLC, the issuer of USDY tokens, also prohibits persons from subscribing for, acquiring or redeeming its tokens if it determines, in its sole discretion, that such activity may constitute a violation of (i) applicable laws, rules or regulations, including but not limited to sanctions restrictions, (ii) the terms of the USDY tokens’ governing documents; or (iii) the issuer’s governing documents and policies. In addition, if Prohibited Persons, directly or indirectly, hold in the aggregate 50% or more beneficial ownership or control of any entity, such entity may also be (or will be, if Prohibited Persons are prohibited as a result of applicable sanctions regulations) prohibited from subscribing for, acquiring or redeeming USDY tokens.
Jurisdiction-Based Restrictions:[](https://docs.ondo.finance/general-access-products/usdy/faq/eligibility#jurisdiction-based-restrictions)
-------------------------------------------------------------------------------------------------------------------------------------------
Individuals residing in or citizens of, and entities organized under the laws of or with a principal place of business in, any jurisdiction in the table set forth below must satisfy one or more of the eligibility requirements set forth opposite the name of such jurisdiction in order to be issued USDY tokens. For convenience purposes only, the below table also lists the key financial thresholds that are generally sufficient for an individual or entity to satisfy the applicable requirements; however, such information is provided only as a guide and does not amend, replace or supersede the requirements set forth under applicable laws, rules or regulations. Please refer to the applicable jurisdiction’s law, rules and regulations for definitions of the defined terms used in the table below. To onboard with the token issuer, Restricted Persons generally will be required to produce evidence that they satisfy the applicable eligibility requirements and to certify or declare their eligible status.
| Jurisdiction | Eligibility Requirements | Financial Thresholds (Individuals) | Financial Thresholds (Entities) |
| --- | --- | --- | --- |
| **Brazil** | “Qualified Investor” (CVM Resolution No. 30, Art. 12) | R$1M in financial investments; or approved technical qualification/certification | Professional investors; investment funds; or investment clubs (managed by Qualified Investors) |
| | “Professional Investor” (CVM Resolution No. 30, Art. 11) | R$10M in financial investments; or non-resident investor; or CVM-accredited professionals | Financial institutions; insurance/capitalization companies; pension entities; investment funds; or investment clubs (managed by CVM-authorized managers) |
| **Any Member State of the European Economic Area** | “Professional Client” (MiFID II, Annex II, Section I); or “Qualified Investor” (Prospectus Regulation (EU) 2017/1129) | EUR 500K financial portfolio; or 10 significant transactions per quarter over 4 quarters; or 1 year of financial sector experience | Regulated financial institutions; or large undertakings meeting 2 of: EUR 20M balance sheet, EUR 40M turnover, EUR 2M own funds |
| **Hong Kong** | “Professional Investor” (Individual) (PI Rules) | HK$8M portfolio value (alone or with associates) | Not applicable |
| | “Professional Investor” (Corporate/Trust) (PI Rules) | Not applicable | Trust corporations with HK$40M total assets; corporations or partnerships with HK$8M portfolio or HK$40M total assets; or investment holding corporations wholly owned by Professional Investors |
| | “Professional Investor” (Institutional) (SFO Schedule 1 Part 1) | Not applicable | Recognized exchange companies; intermediaries; financial institutions; insurers; collective investment schemes; governments; or central banks |
| **Malaysia** | “Sophisticated Investor” (High Net Worth Individual) (CMSA 2007) | RM 3M net personal/joint assets (excluding primary residence); or RM 300K annual income (individual) / RM 400K (joint) | Not applicable |
| | “Sophisticated Investor” (High Net Worth Entity) (CMSA 2007) | Not applicable | Trust companies or public company trustees with RM 10M assets under management; corporations or partnerships with RM 10M net assets; statutory bodies; or pension funds |
| | “Sophisticated Investor” (Accredited Investor) (CMSA 2007) | Not applicable | Unit trust schemes; CMSL holders; licensed banks; closed-end funds; or similar regulated entities |
| **Singapore** | “Accredited Investor” (SFA Section 4A(1)) | S$2M net personal assets (max S$1M from primary residence); or S$1M financial assets (net of liabilities); or S$300K annual income | S$10M net assets |
| | “Institutional Investor” (SFA Section 4A(1)(c)) | Not applicable | Governments; central banks; regulated financial institutions; pension funds; collective investment schemes; or similarly regulated financial institutions |
| **Switzerland** | FinSA “Professional Client” (Article 4(3)-(5)); or CISA “Qualified Investor” | Private investment structures for HNWIs with professional treasury operations; or HNWI with >CHF 500K in assets and relevant experience; or HNWI with >CHF 2M in assets | Regulated financial intermediaries; insurance companies; central banks; public entities; pension funds; companies with professional treasury operations; or large companies meeting 2 of: CHF 20M balance, CHF 40M turnover, CHF 2M equity |
| **United Kingdom** | “Professional Client” (MiFID II, Annex II, Section I); or “Qualified Investor” (Prospectus Regulation (EU) 2017/1129) | EUR 500K financial portfolio; or 10 significant transactions per quarter over 4 quarters; or 1 year of financial sector experience | Regulated financial institutions; or large undertakings meeting 2 of: EUR 20M balance sheet, EUR 40M turnover, EUR 2M own funds |
Please note that Ondo USDY LLC also imposes non-jurisdiction-related eligibility criteria in accordance with its know-your-customer policies, procedures and practices and contractual agreements.
* * *
**USDY Legal Disclaimer**
_USDY tokens have not been registered under the US Securities Act of 1933, as amended ("Act") or the securities or financial instrument laws of any other jurisdiction, and may not be offered or sold in the US or to US persons unless registered under the Act or an exemption from the registration requirements thereof is available. The Tokens are offered and sold in the European Economic Area and the United Kingdom solely to qualified investors, and in Switzerland solely to professional clients. Other jurisdiction-based prohibitions and restrictions apply. Ondo Global Markets (BVI) Limited, the issuer of USDY, is not registered as an investment company under the US Investment Company Act of 1940, as amended, or as an Alternative Investment Fund or Undertaking for Collective Investment in Transferable Securities in the European Economic Area, or under the securities or financial instrument laws of any other jurisdiction. Nothing herein constitutes any offer to sell, or any solicitation of an offer to buy, USDY. Nothing herein constitutes investing advice. Acquiring USDY involves risks. A USDY holder may incur losses, including total loss of their purchase price. Past performance is not an indication of future results. Additional terms apply. See [docs.ondo.finance/legal/terms-of-service](https://docs.ondo.finance/legal/terms-of-service)
, [docs.ondo.finance/general-access-products/usdy](https://docs.ondo.finance/general-access-products/usdy)
and [ondo.finance/usdy (opens in a new tab)](https://ondo.finance/usdy)
for details._
[FAQ](https://docs.ondo.finance/general-access-products/usdy/faq "FAQ")
[Onboarding & KYC](https://docs.ondo.finance/general-access-products/usdy/faq/onboarding-and-kyc "Onboarding & KYC")
---
# Onboarding & KYC | Ondo Finance
[General-Access Products](https://docs.ondo.finance/general-access-products)
[USDY Token](https://docs.ondo.finance/general-access-products/usdy)
[FAQ](https://docs.ondo.finance/general-access-products/usdy/faq)
Onboarding & KYC
Onboarding & KYC
================
### What's involved in onboarding and KYC?[](https://docs.ondo.finance/general-access-products/usdy/faq/onboarding-and-kyc#whats-involved-in-onboarding-and-kyc)
If you are onboarding as an individual, the process is straightforward. You will be required to provide your basic personal information, verify your identity (by providing a driver's license, passport, or national ID card), provide the wallet address where you will receive your Tokens, and review and complete the required legal and tax forms.
The process normally takes about 5 minutes to complete and can be done completely online via our onboarding wizard. Our wizard will also automatically populate the legal and tax forms for you.
If you are onboarding as a legal entity or organization, the initial KYB process usually takes about 15 minutes. After submitting your KYB information, within a few days you will be contacted by our onboarding team to complete the process.
In both cases, you can begin the process by visiting [https://ondo.finance/usdy (opens in a new tab)](https://ondo.finance/usdy)
### Once I submit my onboarding materials, how long until they are reviewed?[](https://docs.ondo.finance/general-access-products/usdy/faq/onboarding-and-kyc#once-i-submit-my-onboarding-materials-how-long-until-they-are-reviewed)
We generally try to review all materials within 3-4 [Business Days](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#what-is-a-business-day)
. However, during periods of high demand we could take substantially longer. Either way, you will receive an email when your materials have been reviewed, and you can always check the status of your onboarding by logging into your Ondo account. If your account indicates that all your materials have been successfully submitted and you still have not heard back after 2 weeks, please contact us at [support@ondo.finance](mailto:support@ondo.finance)
.
### During KYC, I'm being asked to list owners who own more than 25% of the investing entity, but the owner is _another_ entity. What do I do?[](https://docs.ondo.finance/general-access-products/usdy/faq/onboarding-and-kyc#during-kyc-im-being-asked-to-list-owners-who-own-more-than-25-of-the-investing-entity-but-the-owner-is-another-entity-what-do-i-do)
To determine ultimate ownership, you need to go all the way back up to the top until you get to natural persons. For example, let's say that Fund A was owned 50% by you and 50% by Company B, which (in our example), is in turn owned 50% by Bob, 10% by Sue, and 40% by the Entity C Trust. Then you'd have to list yourself, Bob and the trust (stopping at the trust because that's not 'owned' by any individuals). If _no one_ owned more than 25% of Company B, you'd just list yourself. If no person is more than a 25% ultimate owner, you can just list ‘None'.
### What does Ondo look for during onboarding and KYC? Do you reject or block sanctioned people?[](https://docs.ondo.finance/general-access-products/usdy/faq/onboarding-and-kyc#what-does-ondo-look-for-during-onboarding-and-kyc-do-you-reject-or-block-sanctioned-people)
In addition to ensuring you meet our [geographical eligibility criteria](https://docs.ondo.finance/general-access-products/usdy/faq/eligibility)
, we also check to see if applicants are listed on many of the most common sanctions lists, and will not allow anyone so flagged to complete onboarding.
### I made a mistake during the onboarding process. How do I go back?[](https://docs.ondo.finance/general-access-products/usdy/faq/onboarding-and-kyc#i-made-a-mistake-during-the-onboarding-process-how-do-i-go-back)
For security reasons, you can not go backward in the onboarding process, so you will need to restart it from the beginning. Contact us at [support@ondo.finance](mailto:support@ondo.finance)
and our team can reset your onboarding. We apologize for the inconvenience.
* * *
**USDY Legal Disclaimer**
_USDY tokens have not been registered under the US Securities Act of 1933, as amended ("Act") or the securities or financial instrument laws of any other jurisdiction, and may not be offered or sold in the US or to US persons unless registered under the Act or an exemption from the registration requirements thereof is available. The Tokens are offered and sold in the European Economic Area and the United Kingdom solely to qualified investors, and in Switzerland solely to professional clients. Other jurisdiction-based prohibitions and restrictions apply. Ondo Global Markets (BVI) Limited, the issuer of USDY, is not registered as an investment company under the US Investment Company Act of 1940, as amended, or as an Alternative Investment Fund or Undertaking for Collective Investment in Transferable Securities in the European Economic Area, or under the securities or financial instrument laws of any other jurisdiction. Nothing herein constitutes any offer to sell, or any solicitation of an offer to buy, USDY. Nothing herein constitutes investing advice. Acquiring USDY involves risks. A USDY holder may incur losses, including total loss of their purchase price. Past performance is not an indication of future results. Additional terms apply. See [docs.ondo.finance/legal/terms-of-service](https://docs.ondo.finance/legal/terms-of-service)
, [docs.ondo.finance/general-access-products/usdy](https://docs.ondo.finance/general-access-products/usdy)
and [ondo.finance/usdy (opens in a new tab)](https://ondo.finance/usdy)
for details._
[Eligibility](https://docs.ondo.finance/general-access-products/usdy/faq/eligibility "Eligibility")
[Investing & Redeeming](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming "Investing & Redeeming")
---
# Investing & Redeeming | Ondo Finance
[General-Access Products](https://docs.ondo.finance/general-access-products)
[USDY Token](https://docs.ondo.finance/general-access-products/usdy)
[FAQ](https://docs.ondo.finance/general-access-products/usdy/faq)
Investing & Redeeming
Investing & Redeeming
=====================
Investing[](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#investing)
----------------------------------------------------------------------------------------------------------
### What is the minimum I can invest or redeem?[](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#what-is-the-minimum-i-can-invest-or-redeem)
Currently the minimum for investment or redemption is $500, but we expect this minimum to decrease substantially over time. Our goal is to enable anyone that meets our [eligibility criteria](https://docs.ondo.finance/general-access-products/usdy/faq/eligibility#who-can-invest-in-usdy-who-can-redeem-who-can-trade-it)
to invest or redeem. We also support investments via USD bank wire for amounts of $100,000 or more. At this time, however, redemption for [Temporary Global Certificates](https://docs.ondo.finance/general-access-products/usdy/how-it-works#step-3-certificate-and-usdyc-generation)
(i.e. prior to your token issuance) is only available for amounts greater than $100,000.
### How or what forms of payment / currency can I use to invest?[](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#how-or-what-forms-of-payment--currency-can-i-use-to-invest)
Currently we only support investing with USDC, though we may need to expand to other stablecoins in the future. We also support USD wire for investments of $100,000 or more. If you would like to make a USD wire investment, please contact us at [support@ondo.finance](mailto:support@ondo.finance)
.
### Is the minimum relevant for all deposits and redemptions or just the first one?[](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#is-the-minimum-relevant-for-all-deposits-and-redemptions-or-just-the-first-one)
All deposits and redemptions.
### How quickly after I invest can I expect my Tokens?[](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#how-quickly-after-i-invest-can-i-expect-my-tokens)
As you can read about under [How it Works](https://docs.ondo.finance/general-access-products/usdy/how-it-works)
, after you invest, you will typically receive your Temporary Global Certificate within 2-3 [Business Days](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#what-is-a-business-day)
after depositing. The Temporary Global Certificate represents your ownership in USDY. To comply with applicable US regulations, however, you will not be able to claim your transferable Tokens until the Restricted Period for your Certificate ends; this is usually between 40 and 50 days from the time you deposited funds (depending upon exactly when we received your investment). For more information, see [How it Works](https://docs.ondo.finance/general-access-products/usdy/how-it-works)
.
### How long after investing do I start earning yield?[](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#how-long-after-investing-do-i-start-earning-yield)
See our answer [here](https://docs.ondo.finance/general-access-products/usdy/faq/economics-and-fees#how-quickly-after-investing-do-i-start-earning-yield)
.
### Can any type of wallet or account hold USDY?[](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#can-any-type-of-wallet-or-account-hold-usdy)
Currently, Ethereum EOAs (i.e. personal wallets, Metamask, etc) and multi-sigs are supported, but custody accounts (e.g. Coinbase or Binance) are not.
### Are we allowed to specify more than one address?[](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#are-we-allowed-to-specify-more-than-one-address)
If you would like to add more addresses to your USDY account, please contact us at [support@ondo.finance](mailto:support@ondo.finance)
.
In the future, users will have the ability to manage multiple wallet and bank accounts within their Ondo account. Currently, changes to registered wallets must be coordinated through our support staff. Please note that only one wallet can be designated as the primary wallet at any given time, and it will serve as the default address for subscriptions and redemptions. For further assistance on this matter, feel free to contact our support team.
### Are there offering documents like a prospectus, PPM, or loan documents I can see?[](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#are-there-offering-documents-like-a-prospectus-ppm-or-loan-documents-i-can-see)
To comply with US laws and regulations, we are only able to provide such materials to investors who successfully complete our [onboarding process](https://docs.ondo.finance/general-access-products/usdy/faq/onboarding-and-kyc)
to prove [eligibility](https://docs.ondo.finance/general-access-products/usdy/faq/eligibility)
. You will have an opportunity to review all materials prior to investing.
### I want to invest via bank wire. How do I do that?[](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#i-want-to-invest-via-bank-wire-how-do-i-do-that)
Bank wire deposits are only available to those investing $100,000 or more. You will need to provide us with account information for the sending account. Include the account number, ABA/SWIFT Number, name of your bank, and the name on the account. You will also be given a specific code, which you will need to include in the memo/notes section of your wire. Finally, once the wire is sent, you will need to provide us with the unique identifier assigned by your bank to the transaction once the wire has been sent. Depending upon your bank, this might be called a MT103 Message, a UETR, or an IMAD. You will likely have to ask your bank to provide this to you. To begin this process, please contact us at [support@ondo.finance](mailto:support@ondo.finance)
.
### How do subscribe on a network other than Ethereum?[](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#how-do-subscribe-on-a-network-other-than-ethereum)
All subscriptions must be made via USDC on Ethereum, or via USD bank wire (available for subscriptions over $100,000). If you would like the USDY tokens for your subscription to be minted on a [different network](https://docs.ondo.finance/general-access-products/usdy/faq/eligibility#are-there-any-other-ways-to-acquire-usdy)
on which USDY is natively available, please contact us at [support@ondo.finance](mailto:support@ondo.finance)
.
Redeeming[](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#redeeming)
----------------------------------------------------------------------------------------------------------
### What Tokens or currencies can I receive upon redemption?[](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#what-tokens-or-currencies-can-i-receive-upon-redemption)
To comply with US regulations, redemptions must be made in fiat currency and only to bank accounts outside the US; payouts in the form of stablecoins are not allowed. Currently we only support USD wire transfers, so please make sure that any bank account you wish to use can accept USD. If you provide us with a bank account that does not accept USD, wires we send you may be rejected, delaying receipt of your funds.
### I just made an investment. How quickly can I redeem?[](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#i-just-made-an-investment-how-quickly-can-i-redeem)
If you are redeeming more than $100,000, you can submit a redemption request as soon as you receive your Temporary Global Certificate. If you wish to redeem less than this, you must wait until your Tokens are minted, which takes between 40-50 days from the time of your deposit, depending on exactly when it was made.
### Can I submit a redemption request at any time?[](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#can-i-submit-a-redemption-request-at-any-time)
If you are redeeming Tokens, yes. If you are redeeming one or more Temporary Global Certificates that have not yet been converted to Tokens and meet the [minimum early redemption threshold](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#i-just-made-an-investment-how-quickly-can-i-redeem)
, the only other time you would need to wait is during the two-Business-Day period right before your Tokens are minted (this minting date is also known as the “Restricted Period End Date”, which you can find on your Temporary Global Certificate). To ensure accounting accuracy, once this period starts you will typically need to wait until your Tokens are issued and then redeem them via the normal process via our website.
### Once I submit a redemption request, how long before I get my money?[](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#once-i-submit-a-redemption-request-how-long-before-i-get-my-money)
Once you receive your Tokens, you can submit your redemption request on our platform at any time and your redemption will be processed within five Business Days. If you email us to request a redemption of your Temporary Global Certificates prior to your Tokens being issued, then, subject to you meeting the [minimum early redemption threshold](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#i-just-made-an-investment-how-quickly-can-i-redeem)
, we will process your redemption within five Business Days of receiving both (a) your request for redemption and (b) valid wire instructions to a USD-denominated, non-US bank account.
If we receive your redemption request before 8pm UTC on any given day, we will typically begin the redemption process on the next Business Day. For example, if you requested a redemption on Tuesday, we will typically begin the redemption process on Wednesday. Once the redemption process starts, it usually takes another 1-2 Business Days for us to initiate the wire transfer to your account. Note that for early redemption requests of Temporary Global Certificates, it may take a bit longer.
### How do I request a redemption?[](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#how-do-i-request-a-redemption)
It depends if your Tokens have been minted yet or not. If you wish to redeem your Tokens, you can do so via our web app. If you wish to redeem your [Temporary Global Certificates](https://docs.ondo.finance/general-access-products/usdy/how-it-works#step-3-certificate-and-usdyc-generation)
_prior_ to your Tokens being minted, you can contact us at [support@ondo.finance](mailto:support@ondo.finance)
.
### How do request a redemption on network other than Ethereum?[](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#how-do-request-a-redemption-on-network-other-than-ethereum)
If you wish to redeem USDY tokens on a [different network](https://docs.ondo.finance/general-access-products/usdy/faq/eligibility#are-there-any-other-ways-to-acquire-usdy)
on which USDY is natively available, please contact us at [support@ondo.finance](mailto:support@ondo.finance)
. Please note that all redemptions must be made via USD bank wires to bank accounts outside the US.
### If I redeem or transfer my rUSDY tokens before the yield due is accrued, will I still accrue or receive that yield?[](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#if-i-redeem-or-transfer-my-rusdy-tokens-before-the-yield-due-is-accrued-will-i-still-accrue-or-receive-that-yield)
No. Due to [the way that rebasing works](https://docs.ondo.finance/general-access-products/usdy/rebasing)
, you would not accrue or receive that yield on the transferred tokens. Because rebasing in effect increases the number of rUSDY tokens in your wallet proportional to the number of tokens in your wallet at the time of rebase, if you have already redeemed (or transferred) those tokens, your “base” of tokens has already decreased.
Keep this in mind when redeeming or transferring tokens.
### Let’s say I transfer my USDY or rUSDY tokens to another party. Who gets the accrued yield for that day, me or them?[](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#lets-say-i-transfer-my-usdy-or-rusdy-tokens-to-another-party-who-gets-the-accrued-yield-for-that-day-me-or-them)
The general rule to keep in mind is this: whoever holds the tokens at the time of the price update gets the yield.
### So you will always redeem 1 rUSDY for 1 USD?[](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#so-you-will-always-redeem-1-rusdy-for-1-usd)
Legally, an rUSDY token is a fractional representation of a locked USDY token, which in turn is interest-bearing tokenized debt secured by short-term US Treasuries and bank demand deposits. The Reference Token Price per rUSDY token, then, is equal to (a) the total number of USDY tokens locked in the wrapper contract times (b) the Reference Token Price per USDY token, the product of which is divided by the total number of rUSDY tokens. (See [here](https://docs.ondo.finance/general-access-products/usdy/basics#understanding-rusdy)
for more details.) The wrapper contract adjusts the number of rUSDY in existence based upon the Reference Token Price of the underlying USDY token such that the value of an rUSDY token remains 1 USD.
Tax Forms[](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#tax-forms)
----------------------------------------------------------------------------------------------------------
### Where can I find my W-8 tax form? How do I update it?[](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#where-can-i-find-my-w-8-tax-form-how-do-i-update-it)
If you are an individual you can visit your [account page (opens in a new tab)](https://ondo.finance/account)
and find your W-8 tax form on the last page of your USDY Subscription Document Packet. If (a) you are redeeming on behalf of an organization and wish to see the latest W-8 we have on file, OR (b) you are an individual or an entity and wish to update your tax information, please contact us at [support@ondo.finance](mailto:support@ondo.finance)
. If you have never completed a W8 form before, please read the rest of this section.
### Which W-8 tax form do I need to use?[](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#which-w-8-tax-form-do-i-need-to-use)
We cannot provide specific guidance for your situation so please check with your tax adviser. However, here is some general information that may help you:
* **Individuals:** If you receive a salary or share in the profits of a US Business, then the W-8ECI is likely the appropriate form. If not, it's likely the W-8BEN.
* **Business Entities that act as intermediaries or flow-through entities** generally use Form W-8IMY. If the business is not an intermediate or flow-through, your decision depends on whether the entity has income effectively connected with a US trade or business. If it does, you should likely complete Form W-8ECI. If it doesn't, you should likely complete Form W-8BEN-E.
* **Governments and non-profit or tax-exempt organizations** should complete Form W-8EXP to certify their foreign status and, if applicable, claim an exemption or receive reduced withholding.
Remember, these guidelines are simplified, and the specifics of US tax law can be complex. Always consult a tax professional or the IRS for advice tailored to your circumstances.
| Type of W-8 Form | Demographics |
| --- | --- |
| **[Form W-8 BEN (opens in a new tab)](https://www.irs.gov/pub/irs-pdf/fw8ben.pdf) ** [Instructions (opens in a new tab)](https://www.irs.gov/pub/irs-pdf/iw8ben.pdf)
**Most Common For Individuals** | Foreign **individuals** who **receive certain types of income** in the US |
| **[Form W-8 BEN-E (opens in a new tab)](https://www.irs.gov/pub/irs-pdf/fw8bene.pdf) ** [Instructions (opens in a new tab)](https://www.irs.gov/pub/irs-pdf/iw8bene.pdf) | Foreign entities who receive certain types of income in the US |
| **[Form W-8 ECI (opens in a new tab)](https://www.irs.gov/pub/irs-pdf/fw8eci.pdf) ** [Instructions (opens in a new tab)](https://www.irs.gov/pub/irs-pdf/iw8eci.pdf) | Foreign individuals who engage in a trade or business in the US and receive income from US sources |
| **[Form W-8 EXP (opens in a new tab)](https://www.irs.gov/pub/irs-pdf/fw8exp.pdf) ** [Instructions (opens in a new tab)](https://www.irs.gov/pub/irs-pdf/iw8exp.pdf) | Used by certain payees in order to claim a reduction of - or exclusion from- tax withholding |
| **[Form W-8 IMY (opens in a new tab)](https://www.irs.gov/pub/irs-pdf/fw8imy.pdf) ** [Instructions (opens in a new tab)](https://www.irs.gov/pub/irs-pdf/iw8imy.pdf) | Intended for intermediaries- should not be used by beneficial owners in a business |
### The W-8 Form is asking me for a Taxpayer Identification Number (TIN) or an Individual Taxpayer Identification Number (ITIN). What should I do?[](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#the-w-8-form-is-asking-me-for-a-taxpayer-identification-number-tin-or-an-individual-taxpayer-identification-number-itin-what-should-i-do)
If you already have been issued a TIN or an ITIN by the IRS, please list it on the form. Beyond that, we cannot provide specific guidance for your situation so please check with the IRS or your tax adviser. However, most people or entities that do not already have such a number do not need to obtain one for the purposes of this form and can leave this field blank.
Timing[](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#timing)
----------------------------------------------------------------------------------------------------
### What is the cutoff time each day for subscription and redemption requests?[](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#what-is-the-cutoff-time-each-day-for-subscription-and-redemption-requests)
8pm UTC on each [Business Day](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#what-is-a-business-day)
. Any subscription or redemption requests received prior to that will be considered as having been made that day. Any request received after that will be treated “as if” it had been made on the next Business Day.
### What is a “Business Day”?[](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#what-is-a-business-day)
A Business Day shall mean any day that is not (a) a Saturday, (b) Sunday, (c) any other day on which banks in Wilmington, Delaware, are authorized or obligated by law or executive order to be closed or (d) any other day on which the Federal Reserve Bank of Philadelphia is closed.
Other[](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#other)
--------------------------------------------------------------------------------------------------
### What if I lose my Temporary Global Certificate or Token?[](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#what-if-i-lose-my-temporary-global-certificate-or-token)
Because USDY tokens designed to be a bearer instrument like a stablecoin, if you lose your Tokens there is not much we can do. If you lose your Temporary Global Certificate prior to claiming your Tokens, however, you can always re-download your certificate by logging into your Ondo account.
### What happens if USDC fails/de-pegs?[](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#what-happens-if-usdc-failsde-pegs)
If USDC de-pegs after an investment has been processed, there is no adverse effect on USDY holders. Between the time an investor deposits USDC to a crypto exchange account (e.g., Coinbase Prime) owned by Ondo USDY LLC and the time the issuer converts the USDC to US Dollars (and vice versa), the investor assumes all benefits (risks) of any appreciation (depreciation) in the crypto asset’s value. Under normal circumstances, Ondo USDY LLC converts USDC to USD at 1:1. In the event of any material de-pegging, Ondo USDY LLC will contact the lender prior to converting any assets, which may potentially delay the transaction.
* * *
**USDY Legal Disclaimer**
_USDY tokens have not been registered under the US Securities Act of 1933, as amended ("Act") or the securities or financial instrument laws of any other jurisdiction, and may not be offered or sold in the US or to US persons unless registered under the Act or an exemption from the registration requirements thereof is available. The Tokens are offered and sold in the European Economic Area and the United Kingdom solely to qualified investors, and in Switzerland solely to professional clients. Other jurisdiction-based prohibitions and restrictions apply. Ondo Global Markets (BVI) Limited, the issuer of USDY, is not registered as an investment company under the US Investment Company Act of 1940, as amended, or as an Alternative Investment Fund or Undertaking for Collective Investment in Transferable Securities in the European Economic Area, or under the securities or financial instrument laws of any other jurisdiction. Nothing herein constitutes any offer to sell, or any solicitation of an offer to buy, USDY. Nothing herein constitutes investing advice. Acquiring USDY involves risks. A USDY holder may incur losses, including total loss of their purchase price. Past performance is not an indication of future results. Additional terms apply. See [docs.ondo.finance/legal/terms-of-service](https://docs.ondo.finance/legal/terms-of-service)
, [docs.ondo.finance/general-access-products/usdy](https://docs.ondo.finance/general-access-products/usdy)
and [ondo.finance/usdy (opens in a new tab)](https://ondo.finance/usdy)
for details._
[Onboarding & KYC](https://docs.ondo.finance/general-access-products/usdy/faq/onboarding-and-kyc "Onboarding & KYC")
[USDYc](https://docs.ondo.finance/general-access-products/usdy/faq/usdyc "USDYc")
---
# USDY Legal Disclaimer | Ondo Finance
[General-Access Products](https://docs.ondo.finance/general-access-products)
[USDY Token](https://docs.ondo.finance/general-access-products/usdy)
USDY Legal Disclaimer
USDY Legal Disclaimer
=====================
USDY tokens have not been registered under the US Securities Act of 1933, as amended ("Act") or the securities or financial instrument laws of any other jurisdiction, and may not be offered or sold in the US or to US persons unless registered under the Act or an exemption from the registration requirements thereof is available. The Tokens are offered and sold in the European Economic Area and the United Kingdom solely to qualified investors, and in Switzerland solely to professional clients. Other jurisdiction-based prohibitions and restrictions apply. Ondo Global Markets (BVI) Limited, the issuer of USDY, is not registered as an investment company under the US Investment Company Act of 1940, as amended, or as an Alternative Investment Fund or Undertaking for Collective Investment in Transferable Securities in the European Economic Area, or under the securities or financial instrument laws of any other jurisdiction. Nothing herein constitutes any offer to sell, or any solicitation of an offer to buy, USDY. Nothing herein constitutes investing advice. Acquiring USDY involves risks. A USDY holder may incur losses, including total loss of their purchase price. Past performance is not an indication of future results. Additional terms apply. See [docs.ondo.finance/legal/terms-of-service](https://docs.ondo.finance/legal/terms-of-service)
, [docs.ondo.finance/general-access-products/usdy](https://docs.ondo.finance/general-access-products/usdy)
and [ondo.finance/usdy (opens in a new tab)](https://ondo.finance/usdy)
for details.
[Partners & Media](https://docs.ondo.finance/general-access-products/usdy/faq/partners-and-media "Partners & Media")
[Qualified-Access Products](https://docs.ondo.finance/qualified-access-products "Qualified-Access Products")
---
# USDYc | Ondo Finance
[General-Access Products](https://docs.ondo.finance/general-access-products)
[USDY Token](https://docs.ondo.finance/general-access-products/usdy)
[FAQ](https://docs.ondo.finance/general-access-products/usdy/faq)
USDYc
USDYc
=====
### What is USDYc?[](https://docs.ondo.finance/general-access-products/usdy/faq/usdyc#what-is-usdyc)
USDYc, or “Cooking USDY,” is an onchain bookkeeping representation of the Temporary Global Certificate that is issued when a USDY subscription is made. You can learn more about Temporary Global Certificates [here](https://docs.ondo.finance/general-access-products/usdy/how-it-works#step-3-certificate-and-usdyc-generation)
.
### Can I hold or transfer USDYc?[](https://docs.ondo.finance/general-access-products/usdy/faq/usdyc#can-i-hold-or-transfer-usdyc)
No, USDYc is merely a bookkeeping device of the issuer. USDYc is non-transferable and is held only by the issuer, not by subscribers.
### Why does USDYc exist, if it cannot be transferred or held by subscribers?[](https://docs.ondo.finance/general-access-products/usdy/faq/usdyc#why-does-usdyc-exist-if-it-cannot-be-transferred-or-held-by-subscribers)
USDYc is a means of bringing off-chain data onchain. USDYc is used as an accounting mechanism so that the total number of USDY tokens not yet minted for subscriptions in the Restricted Period is recorded onchain. This allows onchain data aggregators to track USDY subscriptions that are still in the Restricted Period, so that they can accurately report data such as USDY’s TVL.
### When is USDYc minted and burned?[](https://docs.ondo.finance/general-access-products/usdy/faq/usdyc#when-is-usdyc-minted-and-burned)
When a [Temporary Global Certificate](https://docs.ondo.finance/general-access-products/usdy/how-it-works#step-3-certificate-and-usdyc-generation)
is issued, USDYc tokens are minted. The number of USDYc tokens, or “Cooking USDY,” that are minted upon the issuance of the Temporary Global Certificate, is equivalent to the number of USDY tokens that will be minted after the conclusion of the Restricted Period. When the [Restricted Period](https://docs.ondo.finance/general-access-products/usdy/how-it-works#step-3-certificate-and-usdyc-generation)
ends, USDY tokens are minted and the associated USDYc tokens are burned.
* * *
**USDY Legal Disclaimer**
_USDY tokens have not been registered under the US Securities Act of 1933, as amended ("Act") or the securities or financial instrument laws of any other jurisdiction, and may not be offered or sold in the US or to US persons unless registered under the Act or an exemption from the registration requirements thereof is available. The Tokens are offered and sold in the European Economic Area and the United Kingdom solely to qualified investors, and in Switzerland solely to professional clients. Other jurisdiction-based prohibitions and restrictions apply. Ondo Global Markets (BVI) Limited, the issuer of USDY, is not registered as an investment company under the US Investment Company Act of 1940, as amended, or as an Alternative Investment Fund or Undertaking for Collective Investment in Transferable Securities in the European Economic Area, or under the securities or financial instrument laws of any other jurisdiction. Nothing herein constitutes any offer to sell, or any solicitation of an offer to buy, USDY. Nothing herein constitutes investing advice. Acquiring USDY involves risks. A USDY holder may incur losses, including total loss of their purchase price. Past performance is not an indication of future results. Additional terms apply. See [docs.ondo.finance/legal/terms-of-service](https://docs.ondo.finance/legal/terms-of-service)
, [docs.ondo.finance/general-access-products/usdy](https://docs.ondo.finance/general-access-products/usdy)
and [ondo.finance/usdy (opens in a new tab)](https://ondo.finance/usdy)
for details._
[Investing & Redeeming](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming "Investing & Redeeming")
[Transfers](https://docs.ondo.finance/general-access-products/usdy/faq/transfers "Transfers")
---
# Transfers | Ondo Finance
[General-Access Products](https://docs.ondo.finance/general-access-products)
[USDY Token](https://docs.ondo.finance/general-access-products/usdy)
[FAQ](https://docs.ondo.finance/general-access-products/usdy/faq)
Transfers
Transfers
=========
Can I transfer the Tokens?[](https://docs.ondo.finance/general-access-products/usdy/faq/transfers#can-i-transfer-the-tokens)
-----------------------------------------------------------------------------------------------------------------------------
Yes, Tokens can be transferred with anyone within eligible geographies.
* * *
**USDY Legal Disclaimer**
_USDY tokens have not been registered under the US Securities Act of 1933, as amended ("Act") or the securities or financial instrument laws of any other jurisdiction, and may not be offered or sold in the US or to US persons unless registered under the Act or an exemption from the registration requirements thereof is available. The Tokens are offered and sold in the European Economic Area and the United Kingdom solely to qualified investors, and in Switzerland solely to professional clients. Other jurisdiction-based prohibitions and restrictions apply. Ondo Global Markets (BVI) Limited, the issuer of USDY, is not registered as an investment company under the US Investment Company Act of 1940, as amended, or as an Alternative Investment Fund or Undertaking for Collective Investment in Transferable Securities in the European Economic Area, or under the securities or financial instrument laws of any other jurisdiction. Nothing herein constitutes any offer to sell, or any solicitation of an offer to buy, USDY. Nothing herein constitutes investing advice. Acquiring USDY involves risks. A USDY holder may incur losses, including total loss of their purchase price. Past performance is not an indication of future results. Additional terms apply. See [docs.ondo.finance/legal/terms-of-service](https://docs.ondo.finance/legal/terms-of-service)
, [docs.ondo.finance/general-access-products/usdy](https://docs.ondo.finance/general-access-products/usdy)
and [ondo.finance/usdy (opens in a new tab)](https://ondo.finance/usdy)
for details._
[USDYc](https://docs.ondo.finance/general-access-products/usdy/faq/usdyc "USDYc")
[Economics & Fees](https://docs.ondo.finance/general-access-products/usdy/faq/economics-and-fees "Economics & Fees")
---
# Economics & Fees | Ondo Finance
[General-Access Products](https://docs.ondo.finance/general-access-products)
[USDY Token](https://docs.ondo.finance/general-access-products/usdy)
[FAQ](https://docs.ondo.finance/general-access-products/usdy/faq)
Economics & Fees
Economics & Fees
================
### How quickly after investing do I start earning yield?[](https://docs.ondo.finance/general-access-products/usdy/faq/economics-and-fees#how-quickly-after-investing-do-i-start-earning-yield)
For investments made via USDC, you start earning interest as soon as we convert your USDC to USD and initiate the wire of those funds into our investment accounts. For investments made via USD bank wire, you start earning interest as soon as we receive the funds. Note that, in both cases, you may start earning interest even prior to receiving your [Temporary Global Certificate](https://docs.ondo.finance/general-access-products/usdy/how-it-works#step-3-certificate-and-usdyc-generation)
.
### How are the yields on the USDY determined?[](https://docs.ondo.finance/general-access-products/usdy/faq/economics-and-fees#how-are-the-yields-on-the-usdy-determined)
On the first [Business Day](https://docs.ondo.finance/general-access-products/usdy/faq/investing-and-redeeming#what-is-a-business-day)
of each month, we set the Token yield rate for that month. This number is quoted on an annual-rate, APY basis. We then convert that to a daily rate since the interest compounds daily. As example, if the interest rate for June was set to be 4.00% APY the daily rate would be as follows:
(1 + .04)^1/365 - 1 = 0.01074598% (We round to 8 decimals places.)
### How is the price of USDY determined?[](https://docs.ondo.finance/general-access-products/usdy/faq/economics-and-fees#how-is-the-price-of-usdy-determined)
The ‘face value' of the USDY Token price - what we call the Reference Token Price - on any future day is calculated based both upon the current Reference Token Price on the first Business Day of the month and the Token yield rate for that month. When such prices (as well as any other key values such as Token amounts and interest rates) are to be stored in our system, we first do the calculations and then round them to 8 decimal points before storing. For example, if the reference Token price on June 1 was $100.00000000 and the APY for June was 4.00000000%, the Token Reference Price on June 3 would be: $100.00000000\*(1+\[(1 + .04)^1/365 - 1\])^2 = $100.02149311
### What fees does USDY charge?[](https://docs.ondo.finance/general-access-products/usdy/faq/economics-and-fees#what-fees-does-usdy-charge)
We charge no management or performance fees. When you invest in USDY, we earn interest on the bank deposits and Treasuries that we purchase. The interest rate we set monthly on USDY that you receive is generally set to be slightly lower than the interest the banks and Treasuries pay to us, and we earn the difference.
You will also be charged a redemption fee of 20bps on any redemptions.
Finally, you will be assessed an outgoing wire / money transmission fee on any redemptions under $100,000. These wire fees are charged by our service providers; we do not make money off such fees. As of this writing (2023-07-19), this is $30 per wire outgoing international wire but may change at any time. For redemptions at or over $100,000, we will cover those fees.
### How is USDY taxed?[](https://docs.ondo.finance/general-access-products/usdy/faq/economics-and-fees#how-is-usdy-taxed)
USDY is structured to not incur any US federal income tax obligations, including withholding tax and excise tax. Investors will need to consider their local tax laws to determine how to account for the return generated from USDY. In all cases, consult your tax advisor to help you answer specific questions regarding how tax laws apply to you and/or your business.
* * *
**USDY Legal Disclaimer**
_USDY tokens have not been registered under the US Securities Act of 1933, as amended ("Act") or the securities or financial instrument laws of any other jurisdiction, and may not be offered or sold in the US or to US persons unless registered under the Act or an exemption from the registration requirements thereof is available. The Tokens are offered and sold in the European Economic Area and the United Kingdom solely to qualified investors, and in Switzerland solely to professional clients. Other jurisdiction-based prohibitions and restrictions apply. Ondo Global Markets (BVI) Limited, the issuer of USDY, is not registered as an investment company under the US Investment Company Act of 1940, as amended, or as an Alternative Investment Fund or Undertaking for Collective Investment in Transferable Securities in the European Economic Area, or under the securities or financial instrument laws of any other jurisdiction. Nothing herein constitutes any offer to sell, or any solicitation of an offer to buy, USDY. Nothing herein constitutes investing advice. Acquiring USDY involves risks. A USDY holder may incur losses, including total loss of their purchase price. Past performance is not an indication of future results. Additional terms apply. See [docs.ondo.finance/legal/terms-of-service](https://docs.ondo.finance/legal/terms-of-service)
, [docs.ondo.finance/general-access-products/usdy](https://docs.ondo.finance/general-access-products/usdy)
and [ondo.finance/usdy (opens in a new tab)](https://ondo.finance/usdy)
for details._
[Transfers](https://docs.ondo.finance/general-access-products/usdy/faq/transfers "Transfers")
[Trust & Transparency](https://docs.ondo.finance/general-access-products/usdy/faq/trust-and-transparency "Trust & Transparency")
---
# Technology | Ondo Finance
[General-Access Products](https://docs.ondo.finance/general-access-products)
[USDY Token](https://docs.ondo.finance/general-access-products/usdy)
[FAQ](https://docs.ondo.finance/general-access-products/usdy/faq)
Technology
Technology
==========
### Where can I view Ondo smart contracts and addresses?[](https://docs.ondo.finance/general-access-products/usdy/faq/technology#where-can-i-view-ondo-smart-contracts-and-addresses)
[Smart Contract Addresses](https://docs.ondo.finance/addresses)
### Have all of the USDY smart contracts been audited?[](https://docs.ondo.finance/general-access-products/usdy/faq/technology#have-all-of-the-usdy-smart-contracts-been-audited)
Yes, you can see the results of the audits [here](https://docs.ondo.finance/audits)
.
### What chains are USDY available on?[](https://docs.ondo.finance/general-access-products/usdy/faq/technology#what-chains-are-usdy-available-on)
Currently USDY is only on Ethereum, but we may consider expanding it to other chains in the future.
### Will there be a rebasing version of USDY in the future?[](https://docs.ondo.finance/general-access-products/usdy/faq/technology#will-there-be-a-rebasing-version-of-usdy-in-the-future)
Yes. USDY will eventually be available in both rebasing and accumulating versions. Stay tuned for more details on this.
### Do you have a public GitHub account?[](https://docs.ondo.finance/general-access-products/usdy/faq/technology#do-you-have-a-public-github-account)
[https://github.com/ondoprotocol (opens in a new tab)](https://github.com/ondoprotocol)
* * *
**USDY Legal Disclaimer**
_USDY tokens have not been registered under the US Securities Act of 1933, as amended ("Act") or the securities or financial instrument laws of any other jurisdiction, and may not be offered or sold in the US or to US persons unless registered under the Act or an exemption from the registration requirements thereof is available. The Tokens are offered and sold in the European Economic Area and the United Kingdom solely to qualified investors, and in Switzerland solely to professional clients. Other jurisdiction-based prohibitions and restrictions apply. Ondo Global Markets (BVI) Limited, the issuer of USDY, is not registered as an investment company under the US Investment Company Act of 1940, as amended, or as an Alternative Investment Fund or Undertaking for Collective Investment in Transferable Securities in the European Economic Area, or under the securities or financial instrument laws of any other jurisdiction. Nothing herein constitutes any offer to sell, or any solicitation of an offer to buy, USDY. Nothing herein constitutes investing advice. Acquiring USDY involves risks. A USDY holder may incur losses, including total loss of their purchase price. Past performance is not an indication of future results. Additional terms apply. See [docs.ondo.finance/legal/terms-of-service](https://docs.ondo.finance/legal/terms-of-service)
, [docs.ondo.finance/general-access-products/usdy](https://docs.ondo.finance/general-access-products/usdy)
and [ondo.finance/usdy (opens in a new tab)](https://ondo.finance/usdy)
for details._
[Trust & Transparency](https://docs.ondo.finance/general-access-products/usdy/faq/trust-and-transparency "Trust & Transparency")
[Partners & Media](https://docs.ondo.finance/general-access-products/usdy/faq/partners-and-media "Partners & Media")
---
# Trust & Transparency | Ondo Finance
[General-Access Products](https://docs.ondo.finance/general-access-products)
[USDY Token](https://docs.ondo.finance/general-access-products/usdy)
[FAQ](https://docs.ondo.finance/general-access-products/usdy/faq)
Trust & Transparency
Trust & Transparency
====================
### How do I know my funds are safe / protected?[](https://docs.ondo.finance/general-access-products/usdy/faq/trust-and-transparency#how-do-i-know-my-funds-are-safe--protected)
USDY has been designed with transparency and investor protection in mind.
First, USDY has been structured to maximize bankruptcy-remoteness, including issuance from a separate legal entity managed by a distinct Board of Directors with an independent director, segregation of assets from Ondo Finance, Inc., and separate books and accounts.
Second, Ondo Finance has over-collateralized the USDY notes, providing a 3% first-loss position that absorbs short-term fluctuations in US Treasuries prices.
Third, investors in USDY have what's known as a “first security interest” in USDY's underlying bank deposits and Treasuries, with Ankura Trust acting as the collateral agent. As part of maintaining these security interests, we have entered into control agreements with Ankura Trust and each of the banks and custodians holding assets backing USDY. These agreements give Ankura the legal right and obligation in its role as Collateral Agent, subject to USDY Tokenholder approval, to take control of USDY's assets and repay Tokenholders upon the occurrence of certain events of default and upon acceleration of the loans by the vote of USDY holders. The events that trigger such an action include a failure to repay redemptions, a failure to keep USDY adequately capitalized, or Ondo USDY LLC filing for bankruptcy.
Finally, in its additional capacity as Verification Agent, Ankura Trust provides [daily transparency reports (opens in a new tab)](https://www.dropbox.com/scl/fo/375wdvar3rbc7o23nxsgp/AOFY8jhpENaNx9WAw-WPnbY?rlkey=4icqn1z9bez725wywr30fx52a&st=bsxeh8j5&dl=0)
with detailed asset holdings, as well as [monthly reports (opens in a new tab)](https://www.dropbox.com/scl/fo/fk5t99zyihshuak3u1u9v/AMYiYSUwvoL6osa2FX_G_M8?rlkey=0ttmb4ifhdg4ebvhbh8aa3juc&st=fyoof4cu&dl=0)
These mechanisms ensure an institutional-grade level of investor protections that most Tokens, including traditional stablecoins, lack.
### How do you ensure adequate reserves to ensure you can always redeem all Tokens you issue?[](https://docs.ondo.finance/general-access-products/usdy/faq/trust-and-transparency#how-do-you-ensure-adequate-reserves-to-ensure-you-can-always-redeem-all-tokens-you-issue)
The first is overcollateralization with a minimum 3% first-loss position. This means that if we issue a total of $100 worth of USDY, it will always be secured by at least $103 worth of bank deposits and Treasury bills. This collateralization ratio will be monitored daily and must exceed this minimum threshold at the end of every quarter.
### How do you invest the reserves?[](https://docs.ondo.finance/general-access-products/usdy/faq/trust-and-transparency#how-do-you-invest-the-reserves)
In general, we aim to maintain an allocation of 99%+ short-term US Treasuries.
### Where are the assets backing USDY held?[](https://docs.ondo.finance/general-access-products/usdy/faq/trust-and-transparency#where-are-the-assets-backing-usdy-held)
The US Treasuries are held in accounts at highly regarded, regulated institutions. We have onboarded with two US banks to accept deposits for USDY—one is a US Globally Systemically Important Bank (G-SIB) with an S&P (long-term) rating of A+, the other is a US bank with an S&P (long-term) rating of BBB+. Ankura Trust acts as Verification Agent to verify the existence of such deposits on a daily basis.
### What kind of reporting will you provide?[](https://docs.ondo.finance/general-access-products/usdy/faq/trust-and-transparency#what-kind-of-reporting-will-you-provide)
Within 60 days of accepting our first deposits, we started providing daily reports on the status of our reserves. These reports are reviewed by our independent, third-party Verification Agent, Ankura Trust. Ankura then, in accordance with the relevant governing documents, confirms the eligible investments. This information is made public and posted on our website. Reporting for a given day will be posted within three business days. (E.g. the report for Monday will be posted by end of day Thursday.) On a monthly basis, we also provide more detailed reconciliation reports by the 20th of the following month; this report is also reviewed by Ankura in accordance with the relevant governing documents.
Daily reports can be found [here (opens in a new tab)](https://www.dropbox.com/scl/fo/375wdvar3rbc7o23nxsgp/AOFY8jhpENaNx9WAw-WPnbY?rlkey=4icqn1z9bez725wywr30fx52a&st=bsxeh8j5&dl=0)
and monthly reports can be found [here (opens in a new tab)](https://www.dropbox.com/scl/fo/fk5t99zyihshuak3u1u9v/AMYiYSUwvoL6osa2FX_G_M8?rlkey=0ttmb4ifhdg4ebvhbh8aa3juc&st=fyoof4cu&dl=0)
### What happens to USDY if Ondo Finance files for bankruptcy?[](https://docs.ondo.finance/general-access-products/usdy/faq/trust-and-transparency#what-happens-to-usdy-if-ondo-finance-files-for-bankruptcy)
While it is unlikely that Ondo Finance would go bankrupt in the next several years due to its strong capitalization, Ondo USDY LLC itself is a separate entity that isolates investor funds. In the unlikely event of an Ondo Finance bankruptcy, Ondo USDY has been structured in a manner to minimize the risk of consolidating the Ondo USDY assets into an Ondo Finance bankruptcy. See more under [How do I know my funds are safe / protected?](https://docs.ondo.finance/general-access-products/usdy/faq/trust-and-transparency#how-do-i-know-my-funds-are-safe--protected)
### What is the legal structure of Ondo? What's the difference between Ondo Finance, Inc. and Ondo USDY LLC?[](https://docs.ondo.finance/general-access-products/usdy/faq/trust-and-transparency#what-is-the-legal-structure-of-ondo-whats-the-difference-between-ondo-finance-inc-and-ondo-usdy-llc)
Ondo Finance is a technology company building software to support institutional financial market infrastructure. Ondo Finance has raised $24MM from Founders Fund, Pantera, and other venture capital and angel investors. Ondo USDY LLC, the issuer of USDY, is an entity designed for bankruptcy-remoteness, with Ondo Finance acting as its servicer and with rights to appoint the Board of Directors of Ondo USDY LLC. In addition, Ondo Finance holds membership interests in Ondo USDY LLC.
### Who is on the Ondo USDY LLC Board of Directors?[](https://docs.ondo.finance/general-access-products/usdy/faq/trust-and-transparency#who-is-on-the-ondo-usdy-llc-board-of-directors)
_Nathan Allman_
Nathan is the Founder and Chief Executive Officer at Ondo Finance. He previously worked at Goldman Sachs on the Digital Assets team. He also has a background in private credit investing at Prospect Capital Management. Nathan has an A.B. from Brown University.
_Justin Schmidt_
Justin is the President and Chief Operating Officer at Ondo Finance. He previous was the Head of Strategy at Talos, the former Head of Digital Assets at Goldman Sachs, and has over 20 years of investing and capital markets experience. Justin holds a Bachelor's and Master's degree in Computer Science from MIT.
_Sébastien Derivaux_
Sébastien is the Co-Founder and Chef at Steakhouse Financial. He previously created Real-World Finance, the first Core Unit of MakerDAO, where he shepherded financial reporting and Real-World Asset investing. Sébastien holds a PhD in Data Science from Strasbourg University.
* * *
**USDY Legal Disclaimer**
_USDY tokens have not been registered under the US Securities Act of 1933, as amended ("Act") or the securities or financial instrument laws of any other jurisdiction, and may not be offered or sold in the US or to US persons unless registered under the Act or an exemption from the registration requirements thereof is available. The Tokens are offered and sold in the European Economic Area and the United Kingdom solely to qualified investors, and in Switzerland solely to professional clients. Other jurisdiction-based prohibitions and restrictions apply. Ondo Global Markets (BVI) Limited, the issuer of USDY, is not registered as an investment company under the US Investment Company Act of 1940, as amended, or as an Alternative Investment Fund or Undertaking for Collective Investment in Transferable Securities in the European Economic Area, or under the securities or financial instrument laws of any other jurisdiction. Nothing herein constitutes any offer to sell, or any solicitation of an offer to buy, USDY. Nothing herein constitutes investing advice. Acquiring USDY involves risks. A USDY holder may incur losses, including total loss of their purchase price. Past performance is not an indication of future results. Additional terms apply. See [docs.ondo.finance/legal/terms-of-service](https://docs.ondo.finance/legal/terms-of-service)
, [docs.ondo.finance/general-access-products/usdy](https://docs.ondo.finance/general-access-products/usdy)
and [ondo.finance/usdy (opens in a new tab)](https://ondo.finance/usdy)
for details._
[Economics & Fees](https://docs.ondo.finance/general-access-products/usdy/faq/economics-and-fees "Economics & Fees")
[Technology](https://docs.ondo.finance/general-access-products/usdy/faq/technology "Technology")
---
# Partners & Media | Ondo Finance
[General-Access Products](https://docs.ondo.finance/general-access-products)
[USDY Token](https://docs.ondo.finance/general-access-products/usdy)
[FAQ](https://docs.ondo.finance/general-access-products/usdy/faq)
Partners & Media
Partners & Media
================
### My company is an asset manager for clients. Can we partner with you to offer your USDY to our clients through our own platform?[](https://docs.ondo.finance/general-access-products/usdy/faq/partners-and-media#my-company-is-an-asset-manager-for-clients-can-we-partner-with-you-to-offer-your-usdy-to-our-clients-through-our-own-platform)
Once you receive your Tokens, you are free to do with them as you wish, subject to the restrictions described elsewhere in this document. USDY is not offered or sold to “dealers” or “distributors” as defined in the US federal securities laws. If you have some other arrangement in mind, please contact us at [support@ondo.finance](mailto:support@ondo.finance)
.
### I want to reference Ondo in my tweet, blog post, or article. Do you have a logo or media kit I can use?[](https://docs.ondo.finance/general-access-products/usdy/faq/partners-and-media#i-want-to-reference-ondo-in-my-tweet-blog-post-or-article-do-you-have-a-logo-or-media-kit-i-can-use)
Yes, see our [Media Kit (opens in a new tab)](https://ondo-finance.notion.site/Ondo-Media-Kit-3bc0a5aced014cc4b0ef62f1638bbf8e)
.
### I'd like to interview folks from Ondo. Who should I contact?[](https://docs.ondo.finance/general-access-products/usdy/faq/partners-and-media#id-like-to-interview-folks-from-ondo-who-should-i-contact)
Please contact us at [support@ondo.finance](mailto:support@ondo.finance)
.
* * *
**USDY Legal Disclaimer**
_USDY tokens have not been registered under the US Securities Act of 1933, as amended ("Act") or the securities or financial instrument laws of any other jurisdiction, and may not be offered or sold in the US or to US persons unless registered under the Act or an exemption from the registration requirements thereof is available. The Tokens are offered and sold in the European Economic Area and the United Kingdom solely to qualified investors, and in Switzerland solely to professional clients. Other jurisdiction-based prohibitions and restrictions apply. Ondo Global Markets (BVI) Limited, the issuer of USDY, is not registered as an investment company under the US Investment Company Act of 1940, as amended, or as an Alternative Investment Fund or Undertaking for Collective Investment in Transferable Securities in the European Economic Area, or under the securities or financial instrument laws of any other jurisdiction. Nothing herein constitutes any offer to sell, or any solicitation of an offer to buy, USDY. Nothing herein constitutes investing advice. Acquiring USDY involves risks. A USDY holder may incur losses, including total loss of their purchase price. Past performance is not an indication of future results. Additional terms apply. See [docs.ondo.finance/legal/terms-of-service](https://docs.ondo.finance/legal/terms-of-service)
, [docs.ondo.finance/general-access-products/usdy](https://docs.ondo.finance/general-access-products/usdy)
and [ondo.finance/usdy (opens in a new tab)](https://ondo.finance/usdy)
for details._
[Technology](https://docs.ondo.finance/general-access-products/usdy/faq/technology "Technology")
[USDY Legal Disclaimer](https://docs.ondo.finance/general-access-products/usdy/disclaimer "USDY Legal Disclaimer")
---
# Minting & Redeeming | Ondo Finance
[Qualified-Access Products](https://docs.ondo.finance/qualified-access-products)
Minting and Redeeming
Minting & Redeeming
===================
### **What currency or stablecoins can I use to invest in your Qualified Access Funds?**[](https://docs.ondo.finance/qualified-access-products/minting-and-redeeming#what-currency-or-stablecoins-can-i-use-to-invest-in-your-qualified-access-funds)
We currently support investing via USDC, PYUSD, RLUSD, or USD bank wire.
### **What currency or stablecoins can I redeem OUSG for?**[](https://docs.ondo.finance/qualified-access-products/minting-and-redeeming#what-currency-or-stablecoins-can-i-redeem-ousg-for)
We currently support redeeming to USDC, PYUSD, RLUSD, or USD bank wire.
[Cash Management 101](https://docs.ondo.finance/qualified-access-products/cash-management-101 "Cash Management 101")
[Eligibility](https://docs.ondo.finance/qualified-access-products/eligibility "Eligibility")
---
# Overview | Ondo Finance
[Qualified-Access Products](https://docs.ondo.finance/qualified-access-products)
[OUSG Token](https://docs.ondo.finance/qualified-access-products/ousg)
Overview
Overview
========
### Introduction[](https://docs.ondo.finance/qualified-access-products/ousg/overview#introduction)
OUSG (Ondo Short-Term US Government Treasuries) provides liquid exposure primarily to short-term US Treasuries, as well as government-sponsored enterprise (GSE) securities, with 24/7 tokenized subscriptions and redemptions. Investing in US Treasury bills and GSE securities is an ultra low-risk investment option that delivers a stable return while offering deep liquidity. US Treasury bills are widely considered to be the lowest-risk and most liquid investment option available. These characteristics make them an attractive investment option for investors who are seeking safety, stability, and liquidity.
The OUSG portfolio is invested in funds issued by leading asset managers such as BlackRock, Franklin Templeton, WisdomTree, FundBridge Capital, Fidelity, and others, along with bank deposits and USDC for liquidity purposes. You can view an overview of the current portfolio [here (opens in a new tab)](https://ondo.finance/ousg#:~:text=Partners-,Portfolio%20Overview,-As%20of%20November)
. The portfolio may, in the future, include other US Treasury funds and/or direct investments in US Treasuries. OUSG shares are tokenized and can be transferred 24/7.
**Key Features:**
* **Instant, 24/7/365 Minting & Redemption.** When you invest with USDC or PYUSD via our website, you will immediately receive OUSG tokens to the same wallet address from which you invested. You will also be able to redeem your OUSG tokens for USDC or PYUSD instantly as well. For security reasons and subject to the limitations of our service partners, the amount you can instantly mint or redeem in any given 24-hour time period will be limited to the amounts shown on our website ([see here for more detail](https://docs.ondo.finance/qualified-access-products/ousg/instant-limits)
); over time, we will be actively working to increase these limits\*.
* **Low Minimum Investment and Redemption Amounts.** For instant transactions, the minimum amount is $5,000 for both investments and redemptions. For non-instant transactions, our minimum investment and redemption amounts remain at $100K and $50K, respectively.
* **Accumulating (OUSG) and Rebasing (rOUSG) Versions.** OUSG comes in two versions: an “accumulating” version (OUSG), and a “rebasing” version (rOUSG) that stays at a price of 1 USD. Whereas the price of OUSG goes up over time as the value of the underlying assets increase, with rOUSG you simply receive more rOUSG in your wallet; in effect the yield on the underlying assets is “paid out” in the form of additional rOUSG tokens. For example, if you held 100 rOUSG tokens and the price of OUSG was $1.00, which then increased to $1.01, the price of rOUSG would remain at $1.00, but your wallet would now hold 101 rOUSG tokens. This ‘rebasing’ happens automatically when we update the OUSG price, which we will do each business day.
| | OUSG | rOUSG |
| --- | --- | --- |
| Token Type | Accumulating | Rebasing (distributing) |
| Yield Distribution Profile | Reflected through an increasing redemption price (NAV per share) | Distributed as additional rOUSG tokens daily |
| As Treasury Yield Accrues, the Token Price | Increases | Remains at $1.00 |
| Best Suited for | Buy-and-hold cash management (some custodians only support accumulating tokens), collateral in smart contracts | Yield-bearing means of settlement or exchange |
* **Easy, Instant OUSG rOUSG Conversion.** You can easily and instantly [convert](https://docs.ondo.finance/qualified-access-products/ousg/ousg-vs-rebasing-ousg#how-do-i-convert-between-ousg-and-rousg)
back and forth between OUSG and rOUSG on our website at any time.
* **Waived Management Fee.** Our management fee for OUSG remains low at 0.15%. **This fee has been waived until July 1, 2026.**
_\*For amounts that exceed the daily instant-mint or instant-redeem limit, you can always submit ‘non-instant’ subscription and redemption requests by contacting us at [support@ondo.finance](mailto:support@ondo.finance)
._
Any investor [eligible to invest in any of our Qualified Access Funds](https://docs.ondo.finance/qualified-access-products/eligibility)
(and who has completed [onboarding](https://docs.ondo.finance/qualified-access-products/onboarding-and-kyc)
) may invest in OUSG or rOUSG. OUSG and rOUSG tokens may be freely transferred between any investors that have already onboarded to our Qualified Access Funds.
### **How It Works**[](https://docs.ondo.finance/qualified-access-products/ousg/overview#how-it-works)
Say you want to make an instant investment of 100K USDC for OUSG. When you make the deposit, our smart contract automatically take two actions:
1. First, it determines how many OUSG tokens you should receive. The number of OUSG tokens you receive is determined by converting the stablecoins you deposit to USD equivalents (1 USDC = $1.00 USD), and then dividing that amount by the current Net Asset Value (NAV) of the OUSG token. For example, if you deposited 100K USDC worth $100K USD and the NAV was $100/token, you would receive $100,000 / $100 = 1,000 OUSG.
2. Second, it routes your deposited USDC to the Fund’s Coinbase account. Those funds are then used to purchase OUSG’s underlying holdings.
At the end of each Business Day, we update the Net Asset Value (NAV) of the Fund based upon the performance of the underlying investments, along with any accrued fees and/or expenses. The NAV per OUSG Token is then calculated by dividing the NAV of OUSG share class by the total number of OUSG tokens. We then update the OUSG Price Oracle onchain to reflect this updated NAV. Finally, this update of the OUSG price automatically triggers a rebase of the rOUSG tokens, with the updated balance automatically being reflected in your wallet (if you are holding any rOUSG).
When you request an instant redemption of your OUSG tokens, a similar process occurs in reverse. The number of USDC you receive in return for your OUSG is determined by multiplying the number of OUSG you redeem by the then-current NAV (giving a USD value), and then sending the equivalent number of USDC at a fixed value of $1.00 USD per USDC.
### Understanding rOUSG[](https://docs.ondo.finance/qualified-access-products/ousg/overview#understanding-rousg)
**rOUSG = A Type of ‘Wrapped’ OUSG**
It’s important to understand that each rOUSG still corresponds to some amount of “regular” OUSG that is locked in a wrapper contract. For example, let’s say you wanted to make an instant investment of 100K USDC into rOUSG. All of the steps in the above example still hold — the only difference is that, instead of the OUSG tokens being sent to your wallet, they are instead sent into a rOUSG wrapper contract. This wrapper contract then locks the OUSG in the contract, mints the corresponding amount of rOUSG, and send that rOUSG to your wallet. For example, if you had 1,000 OUSG tokens worth $100 each — so a total of $100,000 of value — the 1,000 OUSG would be locked in the wrapper contract, which would then mint 100,000 rOUSG tokens and then send those to your wallet. Conversely, if you wanted to redeem your rOUSG tokens, our main contract would first route the rOUSG tokens to the wrapper contract. This wrapper would then burn the rOUSG tokens and “unlock” the corresponding number of OUSG tokens. These OUSG tokens would be sent back to the OUSG contract, which would then burn them and send you the appropriate amount of USDC.
This means that the _total_ supply of OUSG is comprised of two ‘types’ of OUSG:
* **Wrapped OUSG** - i.e. OUSG that is locked in the rOUSG wrapper contract and corresponds to the ‘reserve’ for the corresponding issued rOUSG.
* **Non-Wrapped OUSG** — i.e. OUSG that _isn’t_ locked in the rOUSG wrapper contract.
There are three important implications of this:
* The “dollar value” that is represented by all rOUSG tokens is exactly equal to the amount of “dollar value” represented by all wrapped OUSG tokens. In other words, `NetAssetValue_rOUSG = NetAssetValue_Wrapped_OUSG` → `NetAssetValue_rOUSG = Num_Wrapped_OUSG_Tokens * NAV_per_OUSG` (NAV = Net Asset Value = the total value of the assets backing the token, after accounting for expenses and liabilities; you can think of the “NAV per token” as the “price” or value of each token)
* Because of this, if you were to add up the total amount of OUSG and the amount of rOUSG, you would be _double counting the value of the wrapped OUSG_, because some of that value is already represented by the rOUSG.
* Therefore, to properly calculate the NAV of the OUSG share class, the appropriate calculation is as follows:
`Total OUSG Share Class Net Asset Value (e.g. both versions) = Num_rOUSG_Tokens * $1.00 + Num_Non-Wrapped_OUSG_Tokens * NAV_per_OUSG`
OR
`Total OUSG Share Class Net Asset Value (e.g. both versions) = (Num_Wrapped_OUSG_Tokens + Num_Non-Wrapped_OUSG_Tokens_ * NAV_per_OUSG`
i.e. the two calculations should result in the same number (adjusting for rounding).
**rOUSG Price Stability via Rebasing**
Rebasing is a mechanism through which the total supply of tokens is adjusted. The basic intuition is that, if we’re trying to keep the price per token at $1.00, as the value of rOUSG’s underlying assets increase in value, we need to increase the number of tokens such that the “value of assets” divided the number of tokens remains constant.
For tokens like OUSG and rOUSG, the redemption value of the rOUSG token can be calculated by dividing the Net Asset Value (NAV) of the rOUSG share class by the number of rOUSG tokens
`NAV_per_rOUSG = NetAssetValue_rOUSG / Num_rOUSG_Tokens`
From above, recall that `NetAssetValue_rOUSG = Num_Wrapped_OUSG_Tokens * NAV_per_OUSG` , so we have
`NAV_per_rOUSG = (Num_Wrapped_OUSG_Tokens * NAV_per_OUSG) / Num_rOUSG_Tokens`
Therefore, as `NAV_per_OUSG` increases as the interest accumulates, therefore, `NAV_per_rOUSG` would _also_ increase…unless we also increased `Num_rOUSG_Tokens`. Since we want to keep `NAV_per_rOUSG` at $1.00, this means that we must increase `Num_rOUSG_Tokens` to keep the price at $1.00.
For more technical details on how rebasing works, you can read more [here](https://docs.ondo.finance/qualified-access-products/ousg/rebasing)
.
For more detailed information about OUSG, please refer to the rest of these support docs, the [fund’s legal docs (opens in a new tab)](https://drive.google.com/drive/folders/1ox0c69HXKSOmAOYp0QT2YeMolZMxhhng?usp=sharing)
, or reach out to us at [support@ondo.finance](mailto:support@ondo.finance)
[OUSG Token](https://docs.ondo.finance/qualified-access-products/ousg "OUSG Token")
[Eligibility & Onboarding](https://docs.ondo.finance/qualified-access-products/ousg/eligibility-&-onboarding "Eligibility & Onboarding")
---
# Qualified-Access Products | Ondo Finance
Qualified-Access Products
Qualified-Access Products
=========================
[📄 Cash Management 101\
----------------------\
\
What is Cash Management?](https://docs.ondo.finance/qualified-access-products/cash-management-101)
[📄 Minting & Redeeming\
----------------------\
\
What currency or stablecoins can I use to invest in your Qualified Access Funds?](https://docs.ondo.finance/qualified-access-products/minting-and-redeeming)
[📄 Eligibility\
--------------\
\
To be eligible to invest in Ondo I LP shares, you must be both an accredited investor and a qualified purchaser. Below are the list of criteria you must meet for each designation. Note that while you only need to meet one (1) criteria under each designation in order to qualify, you must qualify for both designations to be eligible to invest.](https://docs.ondo.finance/qualified-access-products/eligibility)
[📄 Onboarding & KYC\
-------------------\
\
What’s involved in onboarding for your Qualified-Access Funds?](https://docs.ondo.finance/qualified-access-products/onboarding-and-kyc)
[USDY Legal Disclaimer](https://docs.ondo.finance/general-access-products/usdy/disclaimer "USDY Legal Disclaimer")
[Cash Management 101](https://docs.ondo.finance/qualified-access-products/cash-management-101 "Cash Management 101")
---
# Cash Management 101 | Ondo Finance
[Qualified-Access Products](https://docs.ondo.finance/qualified-access-products)
Cash Management 101
Cash Management 101
===================
What is Cash Management?[](https://docs.ondo.finance/qualified-access-products/cash-management-101#what-is-cash-management)
----------------------------------------------------------------------------------------------------------------------------
When you oversee a lot of capital, how you allocate that capital matters. On the one hand, markets can be volatile, so stability and liquidity matters. On the other hand, keeping all your money in stablecoins isn't the best strategy either: inflation will eat away at your purchasing power, and even small returns on large sums of money can add up. Consider that earning 5% on $10 million is $500K. That's enough to extend the runway of a small startup by several months. In this funding environment, that could be the difference between surviving… and not.
**Cash management is the practice of intelligently managing the above tension: stewarding financial resources to get the most out of your money while carefully controlling risk.** It's a common function at most mature organizations. Yet despite its particular importance given market conditions today, many crypto-centric organizations and individuals don't know that much about it. In this article we'll talk about what it is, why it's important, and how it works.
The Basic Process[](https://docs.ondo.finance/qualified-access-products/cash-management-101#the-basic-process)
---------------------------------------------------------------------------------------------------------------
The process of cash management can be summarized in three key steps:
1. Forecast your cash flow and needs
2. Manage your liquidity to meet those needs
3. Revise and update continuously
Let's dive into each.
### 1\. Forecast your cash flow and needs[](https://docs.ondo.finance/qualified-access-products/cash-management-101#1-forecast-your-cash-flow-and-needs)
The first step is to forecast your expected cash flows This means developing a forecast for expected (cash) income and expenses. The goal is to get visibility into how much cash you expect to have on hand, by month, for the next 18-24 months. This is your starting point.
A few pointers here. First, when making such estimates, be conservative. In other words, assume less money is coming in than you expect and more is going out. As part of this, we recommend building out various ‘stress scenarios' that you could envision. What if revenue got cut in half? What if you lost your biggest customer? What if some major piece of equipment needed replacing? What if there was a lawsuit or a regulatory fine? Second, remember that what matters here is cash. This is not the place for accrual accounting. Finally, we recommend converting everything into a single base currency for the this purpose—keep it apples to apples whenever possible.
(Advanced Note: Consider also estimating the maximum \*intra-\*month cash drawdown that might be possible. For example, are any big loans coming due? This step is particularly important for financial organizations or protocols. For example, Maker has over $3.5 _billion_ in DAI outstanding that can be redeemed _at any time._ Maker therefore needs to be sure that, if that were to happen, they have adequate liquid reserves available to cover those redemptions.)
### 2\. Manage your liquidity accordingly[](https://docs.ondo.finance/qualified-access-products/cash-management-101#2-manage-your-liquidity-accordingly)
Once you have an idea of how much cash you're likely to have at what points in time, it's time to start planning how you're going to manage it.
If your forecast shows you might temporarily be short on cash, you can look at ways of reducing expenses, changing vendor terms, or take out loans. If it shows you might completely run **_out_** of cash, then you should take the time to plan a financing, giving yourself ample time to get it closed.
On the other hand, if your forecast show you have excess cash, you'll want to consider how to best invest it.
When it comes cash management investments, you should prioritize the following, in this order:
* **Capital Preservation.** The number one priority is simple: don't lose money. This isn't the place for speculative bets.
* **Liquidity.** You want to be able to redeem your investments for cash fairly quickly.
* **Yield.** You want to have your money working for you to earn a return.
In practice, there's always some degree of trade-off between these three dimensions. For example, cash or (well-backed) stablecoins preserve your capital and are liquid by default, but are not going to earn you much. On the other end of the spectrum (though still within the cash management regime), investments in short-term US Treasury bonds and short-term investment grade corporate bonds generate significantly more yield than stablecoins but typically require a few days to get your cash, should you decide to sell, and may be more volatile than stablecoins so you don't want to be a forced seller in a downturn.
Common practice, then, is to think about dividing your cash needs into three buckets, according to how soon you think you'll need the cash. The sooner you need it, the more liquid and stable (and therefore, the less yielding) an asset you'll want to invest in.
For example, here are the types of assets we might recommend for both TradFi and onchain finance, according to how soon you think you might need access to your capital:
| How Soon You'll Need | TradFi |
| --- | --- |
| 0 - 3 Months | Cash |
| 3 - 12 Months | Money Market + Sweep Accounts + Short-Term US Treasuries |
| 12 Months+ | US Treasuries |
As you can see, in TradFi there are plenty of high-quality options.
It's for these reasons that Ondo has created our funds, making it possible for onchain investors to contribute USDC into high-quality, liquid, real world assets:
* OUSG, backed by short-term US Treasuries
These funds invest (outside of small cash holdings) into bond Exchange-Traded Funds (ETFs) or Money Market Funds (MMF) managed by the largest, most reputable asset managers in the world.
### 3\. Revise and update continuously[](https://docs.ondo.finance/qualified-access-products/cash-management-101#3-revise-and-update-continuously)
Once you've built your cash flow forecasts and made your initial allocations, don't forget to actively monitor your cash position and periodically update your forecasts and allocations accordingly.
Getting Started[](https://docs.ondo.finance/qualified-access-products/cash-management-101#getting-started)
-----------------------------------------------------------------------------------------------------------
The value of a strong cash management program should be obvious, but implementing such a process is a project of its own. In the TradFi world, this might include finding banking, investment, custody, accounting, and audit partners, as well as putting the necessary internal processes and controls in place. In the onchain world, the needs are similar, but with important differences. For example, you'll want to ensure you have a secure place to custody your coins. It's also often the case that DAOs need governance approval to implement a cash management program like this.
If you're new to the world of cash management or could use help setting up your cash management, program, Ondo does provide cash management advisory services for those managing treasuries of $10 million or more. You can reach out to us [here (opens in a new tab)](https://ondo.finance/contact)
to learn more.
[Qualified-Access Products](https://docs.ondo.finance/qualified-access-products "Qualified-Access Products")
[Minting and Redeeming](https://docs.ondo.finance/qualified-access-products/minting-and-redeeming "Minting and Redeeming")
---
# Eligibility | Ondo Finance
[Qualified-Access Products](https://docs.ondo.finance/qualified-access-products)
Eligibility
Eligibility
===========
To be eligible to invest in Ondo I LP shares, you must be both an **accredited investor** and a **qualified purchaser**. Below are the list of criteria you must meet for each designation. Note that while you only need to meet one (1) criteria under each designation in order to qualify, you must qualify for **both** designations to be eligible to invest.
Please note that while you must provide **evidence** that you meet the accredited investor criteria that you select, you must **self-attest** to whatever qualified purchaser criteria you meet.
Note that the most frequently chosen criteria start with the phrase **Common Choice:** in bold.
Possible Accredited Investor Criteria[](https://docs.ondo.finance/qualified-access-products/eligibility#possible-accredited-investor-criteria)
-----------------------------------------------------------------------------------------------------------------------------------------------
[Accredited Investor Definition (opens in a new tab)](https://www.law.cornell.edu/cfr/text/17/230.501)
_Must meet at least one_
**Individuals:**
* **Common Choice:** natural person whose individual net worth, or joint net worth with that person's spouse (or spousal equivalent), at the time of purchase exceeds $1,000,000. (For purposes of calculating net worth individuals should exclude the value of the primary residence and the related amount of indebtedness secured by the primary residence up to its fair market value. Indebtedness secured by the primary residence in excess of the value of the primary residence should be considered a liability and deducted from net worth. In addition, any increase in the amount of indebtedness secured by the primary residence in the sixty (60) days prior to making the investment must be treated as a liability.)
* **Common Choice:** natural person who had an individual income in excess of $200,000 in each of the two most recent years or joint income with that person's spouse (or spousal equivalent) in excess of $300,000 in each of those years and has a reasonable expectation of reaching the same income level in the current year.
* natural person holding in good standing with one or more of the following professional certifications or designations or other credentials: (i) Licensed General Securities Representative (Series 7); (ii) Licensed Private Securities Offerings Representative (Series 82); (iii) Licensed Investment Adviser Representative (Series 65); or (iv) any other professional certification or designation or other credential from an accredited educational institution that the SEC may, from time to time, designate as qualifying an individual for accredited investor status.
* natural person who is deemed to be a "knowledgeable employee" of the Fund, as such term is defined in Rule 3c-5(a)(4) of the Investment Company Act.
* director, executive officer, or general partner of the issuer of the securities being offered or sold, or any director, executive officer, or general partner of a general partner of that issuer.
**Institutions:**
* (i) bank as defined in section 3(a)(2) of the Securities Act, or any savings and loan association or other institution as defined in section 3(a)(5)(A) of the Securities Act whether acting in its individual or fiduciary capacity.
* (ii) broker or dealer registered pursuant to section 15 of the Securities Exchange Act.
* (iii) investment adviser registered pursuant to section 203 of the Investment Advisers Act or registered pursuant to the laws of a state.
* (iv) investment adviser relying on the exemption from registering with the SEC under section 203(l) or (m) of the Investment Advisers Act.
* (v) insurance company as defined in section 2(a)(13) of the Securities Act.
* (vi) investment company registered under the Investment Company Act or a business development company as defined in section 2(a)(48) of that act.
* (vii) Rural Business Investment Company as defined in section 384A of the Consolidated Farm and Rural Development Act.
* (viii) Small Business Investment Company licensed by the US Small Business Administration under section 301(c) or (d) of the Small Business Investment Act of 1958.
* (ix) plan established and maintained by a state, its political subdivisions, or any agency or instrumentality of a state or its political subdivisions, for the benefit of its employees, if such plan has total assets in excess of $5,000,000.
* (x) employee benefit plan within the meaning of ERISA if the investment decision is made by a plan fiduciary, as defined in section 3(21) of such act, which is either a bank, savings and loan association, insurance company, or registered investment adviser, or if the employee benefit plan has total assets in excess of $5,000,000 or, if a self-directed plan, with investment decisions made solely by persons that are accredited investors.
* (xi) private business development company as defined in section 202(a)(22) of the Investment Advisers Act.
* (xii) organization described in section 501(c)(3) of the Code, corporation, Massachusetts or similar business trust, partnership, or limited liability company, not formed for the specific purpose of acquiring the securities offered, with total assets in excess of $5,000,000.
* **Common Choice:** (xiii) trust, with total assets in excess of $5,000,000, not formed for the specific purpose of acquiring the securities offered, whose purchase is directed by a sophisticated person as described in Rule 506(b)(2)(ii).
* (xiv) entity in which all of the equity owners are accredited investors.
* **Common Choice:** (xv) entity, of a type not listed in paragraphs (i) to (xiv), not formed for the specific purpose of acquiring the securities offered, owning investments in excess of $5,000,000.
* (xvi) "family office", as defined in Rule 202(a)(11)(G)-1 under the Investment Advisers Act: (a) with assets under management in excess of $5,000,000, (b) that is not formed for the specific purpose of acquiring the securities offered, and (c) whose prospective investment is directed by a person who has such knowledge and experience in financial and business matters that such family office is capable of evaluating the merits and risks of the prospective investment.
* (xvii) "family client", as defined in Rule 202(a)(11)(G)-1 under the Investment Advisers Act, of a family office meeting the requirements in paragraph (xvi) above and whose prospective investment in the issuer is directed by such family office pursuant to paragraph (xvi)(c) above.
Possible Qualified Purchaser Criteria[](https://docs.ondo.finance/qualified-access-products/eligibility#possible-qualified-purchaser-criteria)
-----------------------------------------------------------------------------------------------------------------------------------------------
[Qualified Purchaser Definition (opens in a new tab)](https://www.law.cornell.edu/uscode/text/15/80a-2#a_51)
[Definition of Investments for purposes of Qualified Purchaser Definition (opens in a new tab)](https://www.law.cornell.edu/cfr/text/17/270.2a51-1)
_Must meet at least one_
* **Common Choice:** (i) natural person (including any person who holds a joint, community property, or other similar shared ownership interest in an issuer that is excepted under section 3(c)(7) of the Investment Company Act with that person's qualified purchaser spouse) who owns not less than $5,000,000 in investments.
* (ii) company that owns not less than $5,000,000 in investments, that was not formed for the specific purpose of investing in the Fund, and that is owned directly or indirectly by or for two or more natural persons who are related as siblings or spouse (including former spouses), or direct lineal descendants by birth or adoption, spouses of such persons, the estates of such persons, or foundations, charitable organizations, or trusts established by or for the benefit of such persons.
* (iii) trust that is not covered by clause (ii) and that was not formed for the specific purpose of investing in the Fund, as to which the trustee or other person authorized to make decisions with respect to the trust, and each settlor or other person who has contributed assets to the trust, is a person described in clause (i), (ii), or (iv).
* **Common Choice:** (iv) person or company that was not formed for the specific purpose of investing in the Fund, acting for its own account or the accounts of other qualified purchasers, who in the aggregate owns and invests on a discretionary basis, not less than $25,000,000 in investments.
* (v) any qualified institutional buyer as defined in Rule 144A under the Securities Act, acting for its own account, the account of another qualified institutional buyer, or the account of a qualified purchaser, provided that (i) a dealer described in paragraph (a)(1)(ii) of Rule 144A shall own and invest on a discretionary basis at least $25,000,000 in securities of issuers that are not affiliated persons of the dealer and (ii) a plan referred to in paragraph (a)(1)(D) or (a)(1)(E) of Rule 144A, or a trust fund referred to in paragraph (a)(1)(F) of Rule 144A that holds the assets of such a plan, will not be deemed to be acting for its own account if investment decisions with respect to the plan are made by the beneficiaries of the plan, except with respect to investment decisions made solely by the fiduciary, trustee or sponsor of such plan.
* (vi) any natural person who is deemed to be a "knowledgeable employee" of the Fund, as such term is defined in Rule 3c-5(a)(4) of the Investment Company Act.
* (vii) any person ("Transferee") who acquires Interests from a person ("Transferor") that is (or was) a qualified purchaser other than the Fund, provided that the Transferee is: (i) the estate of the Transferor; (ii) a person who acquires the Interests as a gift or bequest pursuant to an agreement relating to a legal separation or divorce; or (iii) a company established by the Transferor exclusively for the benefit of (or owned exclusively by) the Transferor and the persons specified in this paragraph.
* (viii) any company, if each beneficial owner of the company's securities is a qualified purchaser.
Jurisdictional Restrictions[](https://docs.ondo.finance/qualified-access-products/eligibility#jurisdictional-restrictions)
---------------------------------------------------------------------------------------------------------------------------
In addition the above criteria you (or your organization, depending upon who is investing) must NOT be located, organized, or a resident in any of the following locations:
* Albania
* Afghanistan
* Belarus
* Bosnia and Herzegovina
* Bulgaria
* Burma
* Central African Republic
* Croatia
* Cuba
* DRC
* Darfur Region of Sudan
* Ethiopia
* Iran
* Iraq
* Kosovo
* Lebanon
* Libya
* Mali
* Montenegro
* Nicaragua
* North Korea
* North Macedonia
* Romania
* Russia
* Serbia
* Slovenia
* Somalia
* South Korea
* South Sudan
* Syria
* Venezuela
* West Bank
* Ukraine: Crimea, Donetsk, Kherson, Luhansk, Zaporizhzhia, Sevastopol
* Yemen
[Minting and Redeeming](https://docs.ondo.finance/qualified-access-products/minting-and-redeeming "Minting and Redeeming")
[Onboarding & KYC](https://docs.ondo.finance/qualified-access-products/onboarding-and-kyc "Onboarding & KYC")
---
# Onboarding & KYC | Ondo Finance
[Qualified-Access Products](https://docs.ondo.finance/qualified-access-products)
Onboarding & KYC
Onboarding & KYC
================
### **What’s involved in onboarding for your Qualified-Access Funds?**[](https://docs.ondo.finance/qualified-access-products/onboarding-and-kyc#whats-involved-in-onboarding-for-your-qualified-access-funds)
The onboarding process can be broken into three steps: KYC, provision of account details, and document signing.
**KYC**
During the KYC process, you will first be asked to provide the following information:
**Entities:**
* Business Name
* Country of Registration
* Article of Existence (e.g. incorporation document)
* List of Directors/Officers
* Business ID number
* Business Address
* If applicable, beneficial owner(s) name, email, and photo ID
**Individuals:**
* Proof of Address
* Government ID
* Social Security or Tax ID Number (if applicable)
**Accredited Investor Evidence:**
* Accredited Investor evidence can be shown via a number of methods such as account statements or cryptocurrency wallets.
This information will be run against standard screening and sanctions lists, and all information will be further reviewed by our onboarding and compliance teams.
**Provision of Account Details**
Assuming your KYC profile is approved, you will need to provide us with the wallet address(es) that will hold our fund tokens. See [here](https://docs.ondo.finance/qualified-access-products/ousg/investing#can-any-type-of-wallet-or-account-hold-ousg)
for the types of wallets that we support.
**Document Signing**
Finally, you will be asked to review and sign our fund documents. (You may review those documents in advance [here (opens in a new tab)](https://drive.google.com/drive/folders/1ox0c69HXKSOmAOYp0QT2YeMolZMxhhng?usp=sharing)
).
[Eligibility](https://docs.ondo.finance/qualified-access-products/eligibility "Eligibility")
[OUSG Token](https://docs.ondo.finance/qualified-access-products/ousg "OUSG Token")
---
# Ousg | Ondo Finance
[Qualified-Access Products](https://docs.ondo.finance/qualified-access-products)
OUSG Token
[📄 Overview\
-----------\
\
Introduction](https://docs.ondo.finance/qualified-access-products/ousg/overview)
[📄 Eligibility & Onboarding\
---------------------------\
\
Who can invest in OUSG? Who can redeem? Who can hold and/or transfer it?](https://docs.ondo.finance/qualified-access-products/ousg/eligibility-&-onboarding)
[📄 Investing\
------------\
\
How do I invest in OUSG?](https://docs.ondo.finance/qualified-access-products/ousg/investing)
[📄 Instant Limitis\
------------------\
\
What are the instant mint and redemption limits?](https://docs.ondo.finance/qualified-access-products/ousg/instant-limits)
[📄 Redeeming\
------------\
\
How do I redeem my OUSG / rOUSG tokens?](https://docs.ondo.finance/qualified-access-products/ousg/redeeming)
[📄 Yield\
--------\
\
How does OUSG earn yield?](https://docs.ondo.finance/qualified-access-products/ousg/yield)
[📄 Fees & Taxes\
---------------\
\
What fees does OUSG charge?](https://docs.ondo.finance/qualified-access-products/ousg/fees-and-taxes)
[📄 OUSG vs Rebasing OUSG (rOUSG)\
--------------------------------\
\
What’s the difference between OUSG and rOUSG?](https://docs.ondo.finance/qualified-access-products/ousg/ousg-vs-rebasing-ousg)
[📄 Rebasing\
-----------\
\
What is rebasing and how does it work? How is it different than airdropping?](https://docs.ondo.finance/qualified-access-products/ousg/rebasing)
[📄 Technical\
------------\
\
What chains is OUSG available on?](https://docs.ondo.finance/qualified-access-products/ousg/technical)
[📄 Trust & Transparency\
-----------------------\
\
What types of reporting or other assurances do I have that your numbers are right?](https://docs.ondo.finance/qualified-access-products/ousg/trust-and-transparency)
[📄 Disclaimer\
-------------\
\
OUSG Legal Disclaimer](https://docs.ondo.finance/qualified-access-products/ousg/disclaimer)
[📄 Regulatory Compliance\
------------------------\
\
What is Ondo's approach to regulatory compliance?](https://docs.ondo.finance/qualified-access-products/ousg/regulatory-compliance)
[📄 Other\
--------\
\
What is a "Business Day"?](https://docs.ondo.finance/qualified-access-products/ousg/other)
[Onboarding & KYC](https://docs.ondo.finance/qualified-access-products/onboarding-and-kyc "Onboarding & KYC")
[Overview](https://docs.ondo.finance/qualified-access-products/ousg/overview "Overview")
---
# Fees & Taxes | Ondo Finance
[Qualified-Access Products](https://docs.ondo.finance/qualified-access-products)
[OUSG Token](https://docs.ondo.finance/qualified-access-products/ousg)
Fees & Taxes
Fees & Taxes
============
### What fees does OUSG charge?[](https://docs.ondo.finance/qualified-access-products/ousg/fees-and-taxes#what-fees-does-ousg-charge)
Ondo charges a management fee of 0.15%, which we have waived until July 1, 2026. Fund expenses are capped at 0.15% per annum. Funds that OUSG itself invests in may also incur expenses, but those fees simply reduce the return the OUSG receives on those assets and are not charged to the Fund directly. Instant minting and redemption may incur additional fees; please see the [OUSG product page (opens in a new tab)](https://ondo.finance/ousg)
for the most up to date information.
### How is OUSG taxed?[](https://docs.ondo.finance/qualified-access-products/ousg/fees-and-taxes#how-is-ousg-taxed)
For US federal income tax purposes, the fund is taxed as a partnership. As a result, the fund itself does not pay income taxes. Instead, the fund’s profits, losses, deductions, and credits “pass through” to the individual partners, who report these on their personal tax returns. The fund will issue Schedule K-1 forms to each limited partner, detailing their share of income, interest, dividends, short-term capital gains or losses, long-term capital gains or losses, deductions, credits, and other tax items. Limited partners will use this information to report their share of the fund’s activity on their individual tax returns. Limited partners may also be subject to state and local taxes based on the fund’s activities and where the partners are located.
Conversion from one version of OUSG to another (i.e. OUSG to rOUSG or vice versa) is not likely to be considered a taxable event.
Disclaimer: Tax laws are complex and subject to change. Specific circumstances can significantly impact tax treatment. Always consult with a qualified tax professional for personalized advice regarding tax matters related to the fund and its investments.
### **Do you withhold taxes for OUSG?**[](https://docs.ondo.finance/qualified-access-products/ousg/fees-and-taxes#do-you-withhold-taxes-for-ousg)
In general, because the fund is taxed as a partnership for US federal income tax purposes, the fund does not typically withhold taxes on behalf of its limited partners. However, the fund is required in specific circumstances to withhold taxes such as withholding obligations for foreign partners subject to withholding tax under certain conditions or limited partners that are subject to backup withholding. If a limited partner fails to provide a valid taxpayer identification number (e.g., a Social Security Number for individuals or an Employer Identification Number for entities), the fund might be required to withhold a specific percentage of that payment. Any payments withheld from limited partners are remitted to the relevant tax authority on behalf of the limited partner.
Disclaimer: Tax laws are complex and subject to change. Specific circumstances can significantly impact tax treatment. Always consult with a qualified tax professional for personalized advice regarding tax matters related to the fund and its investments.
[Yield](https://docs.ondo.finance/qualified-access-products/ousg/yield "Yield")
[OUSG vs Rebasing OUSG (rOUSG)](https://docs.ondo.finance/qualified-access-products/ousg/ousg-vs-rebasing-ousg "OUSG vs Rebasing OUSG (rOUSG)")
---
# Eligibility & Onboarding | Ondo Finance
[Qualified-Access Products](https://docs.ondo.finance/qualified-access-products)
[OUSG Token](https://docs.ondo.finance/qualified-access-products/ousg)
Eligibility & Onboarding
Eligibility & Onboarding
========================
### **Who can invest in OUSG? Who can redeem? Who can hold and/or transfer it?**[](https://docs.ondo.finance/qualified-access-products/ousg/eligibility-&-onboarding#who-can-invest-in-ousg-who-can-redeem-who-can-hold-andor-transfer-it)
Only individuals who have onboarded to our [Qualified-Access Funds](https://docs.ondo.finance/qualified-access-products)
can invest in, redeem, or transfer, or receive OUSG or any other Qualified-Access Product. The most common criteria are individuals with a net worth of over $5M or organizations or entities with over $25M in assets. [See all the ways you can qualify.](https://docs.ondo.finance/qualified-access-products/eligibility)
If you do not meet the eligibility criteria for our Qualified-Access Funds, you may still be able to invest in our General-Access Products like [USDY (opens in a new tab)](https://ondo.finance/usdy)
- you can find out more about eligibility for USDY [here (opens in a new tab)](https://docs.ondo.finance/general-access-products/usdy/faq/eligibility)
. You may also want to consider [Flux Finance (opens in a new tab)](https://fluxfinance.com/)
, a lending protocol we developed that allows you to lend permissionlessly against our other tokens.
### **What’s involved in onboarding and KYC for OUSG?**[](https://docs.ondo.finance/qualified-access-products/ousg/eligibility-&-onboarding#whats-involved-in-onboarding-and-kyc-for-ousg)
OUSG doesn’t have it’s own specific KYC and onboarding process. Instead, you would need to [onboard to our Qualified-Access Funds](https://docs.ondo.finance/qualified-access-products/onboarding-and-kyc)
, which includes OUSG.
[Overview](https://docs.ondo.finance/qualified-access-products/ousg/overview "Overview")
[Investing](https://docs.ondo.finance/qualified-access-products/ousg/investing "Investing")
---
# Investing | Ondo Finance
[Qualified-Access Products](https://docs.ondo.finance/qualified-access-products)
[OUSG Token](https://docs.ondo.finance/qualified-access-products/ousg)
Investing
Investing
=========
### **How do I invest in OUSG?**[](https://docs.ondo.finance/qualified-access-products/ousg/investing#how-do-i-invest-in-ousg)
To invest, you must have first [onboarded to our Qualified-Access Funds](https://docs.ondo.finance/qualified-access-products/onboarding-and-kyc)
. Doing so will enable you to access all such funds, including OUSG. After you have onboarded, you can invest either USD via wire transfer or via any [supported stablecoin](https://docs.ondo.finance/qualified-access-products/minting-and-redeeming#what-currency-or-stablecoins-can-i-use-to-invest-in-your-qualified-access-funds)
.
To make an investment, visit [https://ondo.finance/ousg (opens in a new tab)](https://ondo.finance/ousg)
, connect your wallet, and follow the instructions.
### **What is the minimum I can invest in OUSG?**[](https://docs.ondo.finance/qualified-access-products/ousg/investing#what-is-the-minimum-i-can-invest-in-ousg)
For instant transactions, the minimum amount is $5,000 for both investments and redemptions. For non-instant transactions, our minimum investment and redemption amounts are $100K and $50K, respectively. [Limitations may apply, see here for more detail](https://docs.ondo.finance/qualified-access-products/ousg/instant-limits)
### **How quickly after investing can I expect my OUSG tokens?**[](https://docs.ondo.finance/qualified-access-products/ousg/investing#how-quickly-after-investing-can-i-expect-my-ousg-tokens)
**Instant Mints**
If you instant mint, then upon depositing your stablecoins you will receive your OUSG tokens back to that same wallet ‘instantly’; i.e. within the same transaction. The entire transaction is ‘atomic’, meaning that the entire transaction (i.e. depositing your stables _and_ getting the OUSG in return) will either succeed or fail — there is no scenario where you will deposit funds and not receive your OUSG.
**Non-Instant Mints**
If we receive your money before our daily Cutoff Time of 4pm ET, you will typically receive your OUSG tokens the next [Business Day](https://docs.ondo.finance/qualified-access-products/ousg/other#what-is-a-business-day)
. If we receive the money after the Cutoff, your subscription will be processed the following Business Day, which means your tokens will typically be issued the day after that. For example, if on Monday you requested a non-instant subscription (i.e. sent us money) at 11:00am ET, you will typically receive your tokens by the end of the day on Tuesday. If you sent us the money at 4:30pm ET, however, your request would be considered as having been made on Tuesday, which means you would typically receive your tokens by the end of day on Wednesday.
### **Can any type of wallet or account hold OUSG?**[](https://docs.ondo.finance/qualified-access-products/ousg/investing#can-any-type-of-wallet-or-account-hold-ousg)
Currently, we only support non-custodial wallets: this means EOAs (i.e. wallets like Metamask) or multisigs. We do **_not_** currently support custodial wallets (i.e. Binance, Coinbase, etc.) If you plan to invest from, or withdraw to, a bank account, you will also be asked to provide your wallet information. Note: We do support Fireblocks wallets.
### **Are there offering documents like a prospectus, PPM, or LPA documents I can see?**[](https://docs.ondo.finance/qualified-access-products/ousg/investing#are-there-offering-documents-like-a-prospectus-ppm-or-lpa-documents-i-can-see)
Yes, you can see these documents [here (opens in a new tab)](https://drive.google.com/drive/folders/1ox0c69HXKSOmAOYp0QT2YeMolZMxhhng?usp=sharing)
.
[Eligibility & Onboarding](https://docs.ondo.finance/qualified-access-products/ousg/eligibility-&-onboarding "Eligibility & Onboarding")
[Redeeming](https://docs.ondo.finance/qualified-access-products/ousg/redeeming "Redeeming")
---
# Redeeming | Ondo Finance
[Qualified-Access Products](https://docs.ondo.finance/qualified-access-products)
[OUSG Token](https://docs.ondo.finance/qualified-access-products/ousg)
Redeeming
Redeeming
=========
### **How do I redeem my OUSG / rOUSG tokens?**[](https://docs.ondo.finance/qualified-access-products/ousg/redeeming#how-do-i-redeem-my-ousg--rousg-tokens)
You can redeem your tokens by using the UI on the [OUSG page of our website (opens in a new tab)](https://ondo.finance/ousg)
or by contacting us directly at [support@ondo.finance](mailto:support@ondo.finance)
### **How quickly will I get my money once I redeem?**[](https://docs.ondo.finance/qualified-access-products/ousg/redeeming#how-quickly-will-i-get-my-money-once-i-redeem)
If you do an instant redemption, the redemption takes place as an atomic transaction so you will receive your USDC or PYUSD at the same time as you send in your OUSG (or rOUSG) for redemption. [Limitations may apply, see here for more detail](https://docs.ondo.finance/qualified-access-products/ousg/instant-limits)
For non-instant redemptions, provided that you sent us your tokens for redemption prior to 4pm ET, you will typically receive your funds the next [Business Day](https://docs.ondo.finance/qualified-access-products/ousg/other#what-is-a-business-day)
. If you sent your tokens after that, your redemption request will most likely be processed the following Business Day (meaning your funds will typically be provided the day after that).
For example, if on Monday you requested a non-instant redemption at 11:00am ET, you will typically receive your funds by end of day on Tuesday. If you submitted your tokens for redemption at 4:30pm ET, however, your request would be considered as having been made on Tuesday, which means you would typically receive your funds by the end of the day on Wednesday.
### **If I redeem or transfer my rOUSG tokens before the yield due is paid out, will I still receive that yield?**[](https://docs.ondo.finance/qualified-access-products/ousg/redeeming#if-i-redeem-or-transfer-my-rousg-tokens-before-the-yield-due-is-paid-out-will-i-still-receive-that-yield)
No. Due to [the way that rebasing works](https://docs.ondo.finance/qualified-access-products/ousg/rebasing)
, you would not receive that yield on the transferred tokens. Because rebasing in effect increases the number of rOUSG tokens in your wallet proportional to the number of tokens in your wallet **_at the time of rebase_**, if you have already redeemed (or transferred) those tokens, your “base” of tokens has already decreased.
Keep this in mind when redeeming or transferring tokens.
### **Let’s say I transfer my OUSG or rOUSG tokens to another party. Who gets the yield for that day, me or them?**[](https://docs.ondo.finance/qualified-access-products/ousg/redeeming#lets-say-i-transfer-my-ousg-or-rousg-tokens-to-another-party-who-gets-the-yield-for-that-day-me-or-them)
The general rule to keep in mind is this: whoever holds the tokens at the [time of the price update](https://docs.ondo.finance/qualified-access-products/ousg/yield#how-frequently-and-when-do-you-update-the-onchain-ousg-token-price--nav)
gets the yield.
### **So you will always redeem 1 rOUSG for 1 USDC or 1 USD?**[](https://docs.ondo.finance/qualified-access-products/ousg/redeeming#so-you-will-always-redeem-1-rousg-for-1-usdc-or-1-usd)
Legally, an rOUSG token is a fractional representation of a locked OUSG token, which in turn represents an authoritative membership interest in the OUSG share class of the Fund. The net asset value (NAV) per rOUSG token, then, is equal to (a) the total number of OUSG tokens locked in the wrapper contract times (b) the NAV per OUSG token, the product of which is divided by the total number of rOUSG tokens. (See [here](https://docs.ondo.finance/qualified-access-products/ousg/overview#understanding-rousg)
for more detail.) The wrapper contract adjusts the number of rOUSG in existence based upon the NAV of the underlying OUSG token such that the value of an rOUSG token remains 1 USD.
Whether or not we redeem 1 rOUSG for 1 USDC or another stablecoin will also depend upon the exchange rate between that stablecoin and USD. At the time of this writing (April 2024), we mint and redeem USDC 1:1 with USD.
### **What is the minimum amount of OUSG I can redeem?**[](https://docs.ondo.finance/qualified-access-products/ousg/redeeming#what-is-the-minimum-amount-of-ousg-i-can-redeem)
The minimum for instant redemptions is $5K; the minimum for non-instant redemption is $50K. While at the beginning it’s fine if you wish to non-instant redeem a small ‘test’ amount of OUSG to get comfortable with the process; contact us at [support@ondo.finance](mailto:support@ondo.finance)
### **If I request a redemption on a given day, do I earn yield for that day?**[](https://docs.ondo.finance/qualified-access-products/ousg/redeeming#if-i-request-a-redemption-on-a-given-day-do-i-earn-yield-for-that-day)
No. Provided you submitted a redemption request before the [price update](https://docs.ondo.finance/qualified-access-products/ousg/yield#how-frequently-and-when-do-you-update-the-onchain-ousg-token-price--nav)
, you will not receive the yield for that day.
Note that, for technical reasons, Friday’s price update includes the estimated yield paid out on the underlying assets for Friday and Saturday, while Monday’s update reflects the yield for Sunday and Monday. Price updates on the day immediately proceeding a holiday include the estimated yield to be paid out on that holiday.
[Investing](https://docs.ondo.finance/qualified-access-products/ousg/investing "Investing")
[Instant Limits](https://docs.ondo.finance/qualified-access-products/ousg/instant-limits "Instant Limits")
---
# Instant Minting and Redemption Limits | Ondo Finance
[Qualified-Access Products](https://docs.ondo.finance/qualified-access-products)
[OUSG Token](https://docs.ondo.finance/qualified-access-products/ousg)
Instant Limits
Instant Minting and Redemption Limits
=====================================
Instant minting and instant redemption both have a transaction minimum of $5,000. In addition, they both are subject to certain limitations, as detailed below.
### **Instant Minting**[](https://docs.ondo.finance/qualified-access-products/ousg/instant-limits#instant-minting)
Instant minting has a $50M **Global Limit**. This is the total value of OUSG that can be instantly minted by all investors combined within 24 hours. This Global Limit resets every 24 hours.
There is also an **Individual Limit** of $25M within 24 hours. This is the limit per investor, which also resets every 24 hours.
Please note that instant minting is constrained by whichever of these limits is lowest at the time. In other words, if the remaining Global Limit is less than your remaining Individual Limit, the maximum amount you could instantly mint at that time would be constrained by the remaining Global Limit. If the remaining Global Limit is more than your remaining Individual Limit, the maximum amount you could instantly mint at that time would be constrained by your remaining Individual Limit.
To request a subscription that exceeds your instant minting limit, please contact us at [support@ondo.finance](mailto:support@ondo.finance)
.
### **Instant Redemptions**[](https://docs.ondo.finance/qualified-access-products/ousg/instant-limits#instant-redemptions)
Instant redemptions have a $50M **Global Limit**. This is the total value of OUSG that can be instantly redeemed by all investors combined within 24 hours. This Global Limit resets every 24 hours.
There is also an **Individual Limit** of $25M within 24 hours. This is the limit per investor, which also resets every 24 hours.
Please note that instant redemptions are constrained by whichever of these limits is lowest at the time. In other words, if the remaining Global Limit is less than your remaining Individual Limit, the maximum amount you could instantly redeem at that time would be constrained by the remaining Global Limit. If the remaining Global Limit is more than your remaining Individual Limit, the maximum amount you could instantly redeem at that time would be constrained by your remaining Individual Limit.
Instant Redemptions may also be limited by the availability of USDC tokens for instant redemption that Circle supports.
To request a redemption that exceeds your instant redemption limit, please contact us at [support@ondo.finance](mailto:support@ondo.finance)
.
[Redeeming](https://docs.ondo.finance/qualified-access-products/ousg/redeeming "Redeeming")
[Yield](https://docs.ondo.finance/qualified-access-products/ousg/yield "Yield")
---
# Yield | Ondo Finance
[Qualified-Access Products](https://docs.ondo.finance/qualified-access-products)
[OUSG Token](https://docs.ondo.finance/qualified-access-products/ousg)
Yield
Yield
=====
### **How does OUSG earn yield?**[](https://docs.ondo.finance/qualified-access-products/ousg/yield#how-does-ousg-earn-yield)
The OUSG portfolio is invested in funds issued by leading asset managers such as BlackRock, Franklin Templeton, WisdomTree, FundBridge Capital, Fidelity, and others, along with bank deposits and USDC for liquidity purposes. You can view an overview of the current portfolio [here (opens in a new tab)](https://ondo.finance/ousg#:~:text=Partners-,Portfolio%20Overview,-As%20of%20November)
. The portfolio may, in the future, include other US Treasury funds and/or direct investments in US Treasuries. As these investments accrue yield daily, we recognized this yield by increasing the Net Asset Value (NAV) of the underlying fund, thereby increasing the NAV per OUSG token. For rOUSG, we pay out that yield to rOUSG token holders through [rebasing](https://docs.ondo.finance/qualified-access-products/ousg/rebasing)
.
### **How long after investing do I start earning yield/interest?**[](https://docs.ondo.finance/qualified-access-products/ousg/yield#how-long-after-investing-do-i-start-earning-yieldinterest)
Since yield is effectively incorporated into the price of OUSG — or paid out in additional tokens, in the case of rOUSG — whenever we update the price of OUSG onchain, you start earning yield either the day of your subscription or the next, according to whether you subscribed before or after the price update for the day.
The only exceptions to this are weekends and holidays, since the next price update will not happen until the next Business Day. For example, say you subscribe on Friday after the price update. Since the next price update after that will not happen until Monday, you will not start receiving interest until Monday.
(Technical note: because of the way we’ve implemented the fund mechanics, if you are subscribed prior to the price update on Friday, during that update you will actually receive the expected yield for both Friday and Saturday. If you subscribe any time between immediately after the price update on Friday and the next price update the following Monday, you will receive the yield for both Sunday and Monday.)
### **How frequently (and when) do you update the onchain OUSG token price / NAV?**[](https://docs.ondo.finance/qualified-access-products/ousg/yield#how-frequently-and-when-do-you-update-the-onchain-ousg-token-price--nav)
We typically update the price once every Business Day. We typically aim to do this sometime between 4-6pm ET but, because this is a manual process, it may sometimes take longer.
### **How often does OUSG / rOUSG pay out yield?**[](https://docs.ondo.finance/qualified-access-products/ousg/yield#how-often-does-ousg--rousg-pay-out-yield)
We aim to pay out yield every Business Day based on the [net income received](https://docs.ondo.finance/qualified-access-products/ousg/yield#how-is-the-amount-of-yield-determined)
.
In the event that we are unable to update the price or rebase on a given Business Day, investors holding their tokens will still receive the yield from the ‘missed’ day at the time of the next update. Note that tokenholders who submit a redemption request prior to a price update or rebase on a given day are not paid yield on those tokens for that day. Please also note yield is paid to the holder of the tokens at the time of update; if you have already transferred or redeemed your tokens, you will not receive yield on them. Note that OUSG holders are not ‘paid out’ yield per se; instead, that yield is reinvested into fund, thereby increasing the value of their _existing_ OUSG tokens.
### **In what currency/token does rOUSG pay out yield?**[](https://docs.ondo.finance/qualified-access-products/ousg/yield#in-what-currencytoken-does-rousg-pay-out-yield)
Yield is paid out in the form of additional rOUSG tokens (or fractions thereof). rOUSG holders are paid yield through a process called [rebasing](https://docs.ondo.finance/qualified-access-products/ousg/rebasing)
. (Compare this to OUSG holders, who are not ‘paid out’ yield per se; instead, that OUSG yield is reinvested into fund, thereby increasing the value of the _existing_ OUSG tokens.)
### **How is the amount of yield determined?**[](https://docs.ondo.finance/qualified-access-products/ousg/yield#how-is-the-amount-of-yield-determined)
The amount of yield paid out on a given day is based upon the Net Income received as of the end of the previous Business Day. This Net Income is then allocated ratably across all OUSG and rOUSG holders (e.g. if you held 100% of the OUSG and rOUSG tokens, you’d be allocated 100% of the net income; if you held 25% of the OUSG and rOUSG tokens, you’d be allocated 25% of the net income, etc).
To ensure timely price updates, each Business Day the Fund makes a conservative estimate of the Net Income it expects to receive for the day (including, if immediately followed by a weekend or holiday, any income it expects to accrue to it over those non-business days) based upon historical data. When the Fund then receives final information on the actual income received from its holdings, it makes an additional adjustment to its Net Income on the following Business Day. It does this in order to provide more consistent updates to the OUSG price.
### **When is the APY updated and how is it calculated?**[](https://docs.ondo.finance/qualified-access-products/ousg/yield#when-is-the-apy-updated-and-how-is-it-calculated)
The APY on our [website (opens in a new tab)](https://ondo.finance/ousg)
is generally updated each weekday, excluding holidays. APY is calculated based on the average income, net of expenses, earned over the 30 calendar days preceding and including the day that APY is updated. This yield reflects past performance. Past performance is not indicative of future results. Actual yields may vary depending on market conditions and other factors.
The formula used to calculate the APY is `APY = e^((End NAV - Start NAV) / (30/365)) - 1`
### **When are the 7-Day Yield and 30-Day Yield updated, and how are they calculated?**[](https://docs.ondo.finance/qualified-access-products/ousg/yield#when-are-the-7-day-yield-and-30-day-yield-updated-and-how-are-they-calculated)
The yields on our [website (opens in a new tab)](https://ondo.finance/ousg)
are generally updated each weekday, excluding holidays. 7-Day Yield is calculated based on the average income, net of expenses, earned over the 7 calendar days preceding and including the day that the 7-Day Yield is updated. 30-Day Yield is calculated based on the average income, net of expenses, earned over the 30 calendar days preceding and including the day that the 30-Day Yield is updated. These yields reflect past performance. Past performance is not indicative of future results. Actual yields may vary depending on market conditions and other factors.
The formulas used to calculate the 7-Day Yield and 30-Day Yield are:
* `7-Day Yield = e^((End NAV - Start NAV) / (7/365)) - 1`
* `30-Day Yield = e^((End NAV - Start NAV) / (30/365)) - 1`
### **How can I check to ensure I’m getting the right amount of yield for rOUSG?**[](https://docs.ondo.finance/qualified-access-products/ousg/yield#how-can-i-check-to-ensure-im-getting-the-right-amount-of-yield-for-rousg)
You can calculate your expected account balance by taking your account balance on any given day and multiplying it by the rebasing factor. In the example below, this investor invested $500K before the rebase on Nov 1. The rebasing factor applied on Nov 2 was 1.00014191. 500,000 \* 1.00014191 is 500,070.96. So, if this investor hadn’t done anything else, after the rebase they would expect to see 500,070.96. And so on:
| Date | 1-Nov-23 | 2-Nov-23 | 3-Nov-23 | 6-Nov-23 | 7-Nov-23 | 8-Nov-23 |
| --- | --- | --- | --- | --- | --- | --- |
| DoW | Wed | Thursday | Friday | Monday | Tuesday | Wednesday |
| Rebasing Factor | Not Relevant | 1.00014191 | 1.00017731 | 1.00042325 | 1.00011782 | 1.00000000 |
| Total | 500,000 | 500,070.96 | 500,159.62 | 500,371.32 | 500,430.27 | 500,430.27 |
If this investor had submitted a redemption request of 100K OUSG before the rebase on Tuesday, remember that they would not earn yield on those 100K tokens for Tuesday; at the end of Tuesday they would have 400,070.96 tokens, and that token base is the number of tokens that would be rebased:
| Date | 1-Nov-23 | 2-Nov-23 | 3-Nov-23 | 6-Nov-23 | 7-Nov-23 | 8-Nov-23 |
| --- | --- | --- | --- | --- | --- | --- |
| DoW | Wed | Thursday | Friday | Monday | Tuesday | Wednesday |
| Rebasing Factor | Not Relevant | 1.00014191 | 1.00017731 | 1.00042325 | 1.00011782 | 1.00000000 |
| Deposit | 500,000 | 500,070.96 | | | | |
| Redemption | | (100,000) | | | | |
| Tokens after Rebase | | 400,070.96 | 400,141.89 | 400,311.26 | 400,358.42 | 400,358.42 |
To do a ‘sanity check’ by converting the rebasing factor into an annualized yield, you can calculate `(RebasingFactor-1)*365`
[Instant Limits](https://docs.ondo.finance/qualified-access-products/ousg/instant-limits "Instant Limits")
[Fees & Taxes](https://docs.ondo.finance/qualified-access-products/ousg/fees-and-taxes "Fees & Taxes")
---
# OUSG vs Rebasing OUSG (rOUSG) | Ondo Finance
[Qualified-Access Products](https://docs.ondo.finance/qualified-access-products)
[OUSG Token](https://docs.ondo.finance/qualified-access-products/ousg)
OUSG vs Rebasing OUSG (rOUSG)
OUSG vs Rebasing OUSG (rOUSG)
=============================
### What’s the difference between OUSG and rOUSG?[](https://docs.ondo.finance/qualified-access-products/ousg/ousg-vs-rebasing-ousg#whats-the-difference-between-ousg-and-rousg)
The ‘r’ in rOUSG stands for ‘rebasing’. The difference is that, whereas rOUSG is intended to remain at a price of $1.00 per token (with yield being paid out in the form of additional rOUSG tokens via [rebasing](https://docs.ondo.finance/qualified-access-products/ousg/rebasing)
), in OUSG the yield received gets ‘accumulated’ into the price, meaning the price of OUSG is intended to increase over time. For example, let’s say you held 1 rOUSG token and 1 OUSG token, each worth a dollar, and the [rebasing factor](https://docs.ondo.finance/qualified-access-products/ousg/rebasing)
for the day was 1.10. After rebase, your holdings of both rOUSG and OUSG would be worth $1.10 each. However, whereas you’d now have 1.10 rOUSG (still each worth $1/token), you’d still only have 1 OUSG token, but it’d be worth $1.10.
### How do I decide between OUSG and rOUSG?[](https://docs.ondo.finance/qualified-access-products/ousg/ousg-vs-rebasing-ousg#how-do-i-decide-between-ousg-and-rousg)
While we believe many investors will want to hold rOUSG because of its price stability, certain protocols, exchanges, or custodians may not support rebasing tokens. That said, it is easy to [convert between the two](https://docs.ondo.finance/qualified-access-products/ousg/ousg-vs-rebasing-ousg#how-do-i-convert-between-ousg-and-rousg)
.
### How do I convert between OUSG and rOUSG?[](https://docs.ondo.finance/qualified-access-products/ousg/ousg-vs-rebasing-ousg#how-do-i-convert-between-ousg-and-rousg)
You can easily convert between OUSG and rOUSG using the ‘convert’ option on the [OUSG product page (opens in a new tab)](https://ondo.finance/ousg)
on our website.
[Fees & Taxes](https://docs.ondo.finance/qualified-access-products/ousg/fees-and-taxes "Fees & Taxes")
[Rebasing](https://docs.ondo.finance/qualified-access-products/ousg/rebasing "Rebasing")
---
# Technical | Ondo Finance
[Qualified-Access Products](https://docs.ondo.finance/qualified-access-products)
[OUSG Token](https://docs.ondo.finance/qualified-access-products/ousg)
Technical
Technical
=========
### What chains is OUSG available on?[](https://docs.ondo.finance/qualified-access-products/ousg/technical#what-chains-is-ousg-available-on)
OUSG is available on Ethereum mainnet, Polygon, Solana, and XRP Ledger. Instant minting and redemption is only available on mainnet Ethereum. [Limitations may apply, see here for more detail](https://docs.ondo.finance/qualified-access-products/ousg/instant-limits)
### Are the OUSG smart contracts audited?[](https://docs.ondo.finance/qualified-access-products/ousg/technical#are-the-ousg-smart-contracts-audited)
Yes. You can see the results of our audits [here (opens in a new tab)](https://docs.ondo.finance/audits)
.
[Rebasing](https://docs.ondo.finance/qualified-access-products/ousg/rebasing "Rebasing")
[Trust & Transparency](https://docs.ondo.finance/qualified-access-products/ousg/trust-and-transparency "Trust & Transparency")
---
# Rebasing | Ondo Finance
[Qualified-Access Products](https://docs.ondo.finance/qualified-access-products)
[OUSG Token](https://docs.ondo.finance/qualified-access-products/ousg)
Rebasing
Rebasing
========
### **What is rebasing and how does it work? How is it different than airdropping?**[](https://docs.ondo.finance/qualified-access-products/ousg/rebasing#what-is-rebasing-and-how-does-it-work-how-is-it-different-than-airdropping)
Rebasing is a mechanism through which the total supply of tokens is adjusted. Rebasing works by taking the “base” number of tokens, T, and multiplying it by some “rebasing factor”, RF, to get a new number of tokens. For example, let’s say there were a total of 100 tokens: 10 were held by investor A and 90 by investor B. In a rebasing, we might want to double the total number of tokens (i.e. a rebasing factor of 2). We multiply each investor's balance by the Rebasing Factor — 2 in this case — so after rebase Investor A has 20 tokens and Investor B has 180, for a total of 200 tokens.
The most common reasons for rebasing are to create price stability and to pay out yield, both of which are relevant here. For example, let’s say a token started at a price of $1.00 per token, but then rose in price to $1.10. If we want to bring the price of the token _back_ to $1.00, we could rebase. Let’s go back to our example where investor A holds 10 tokens and B holds 90. Initially, there are 100 total tokens, each at $1.00/token, for a ‘_total_ value’ of $100. If the price of the token rises to $1.10, this means that the ‘total value’ of all tokens is 100 x $1.10 = $110. If we want to reduce the price per token back to $1.00, we need to increase the number of tokens. By how much? By $110/100 = 1.10. If you then multiply the initial number of tokens (100) by the rebasing factor (1.10), you get 100 x 1.10 = 110 tokens. The price per token after rebase is then \[$110 in total value\] / \[110 tokens\] = $1.00 per token.
How can we do this? One way would be to mint and airdrop new tokens to each token holder. This would cost a lot of gas, however, because it requires updating each token contract storage location that represents a user’s balance. Rebasing allows us to adjust all token holder balances in a gas-efficient manner by introducing the concept of user “shares”. A “share” is similar to a share of stock - it can be thought of as a claim on a percentage of the total supply of rOUSG tokens. A user’s balance is then equal to the percentage of total shares they hold, multiplied by the total number of shares:
`NumTokens_User = NumTokens_Total * (NumShares_User / NumShares_Total)`
When we rebase, therefore, we only have to update **_one_** contract storage location: `NumTokens_Total`. As you can see from the formula above, that will increase the balance in your wallet while keeping your **_percentage_** of the total tokens the same. Here’s an example where we increase `NumTokens_Total` from 100 to 200:
| | Investor A Shares | Investor B Shares | Total Number of Shares | Total Supply of rOUSG Tokens | Investor A rOUSG Balance | Investor B rOUSG Balance |
| --- | --- | --- | --- | --- | --- | --- |
| Before Rebasing | 1 | 9 | 10 | 100 | (1/10) \* 100 = 10 rOUSG Tokens | 9/10\* 100 = 90 rOUSG Tokens |
| After Rebasing | 1 | 9 | 10 | 200 (increase) | (1/10) \* 200 = 20 rOUSG Tokens | 9/10 \* 200 = 180 rOUSG Tokens |
And what number do we set the `NumTokens_Total` to be? We set it equal to the Net Asset Value of the Fund as of the end of the previous Business Day. In other words, we set `NumTokens_Total = NetAssetValue`, thereby making `NetAssetValue / NumTokens_Total` equal to $1.00.
The rebasing factor RF that we list on the website, then, is calculated as `RF = NumTokens_Total_New / NumTokens_Total_Old`.
We can use a simple example to check this. Let’s say that on Monday the total number of tokens after rebase (NumTokens\_Total\_Old) was 2 (implying a fund Net Asset Value of $2.00). Let’s also say that at the end of Monday, we had received $2 in net income, so the Net Asset Value of the fund at the end of the day (NetAssetValue) was now $4. This implies that the NAV per token is 4 dollars / 2 tokens = $2/token. To make the NAV per token $1.00 after rebase on Tuesday, we need to double the number of tokens. In this case, the rebasing factor would be $4/2 = 2. If we therefore doubled the number of rOUSG tokens everyone had, the NAV per token would be reduced to $1.
Finally, please note that when your rOUSG balance increases due to rebasing, while you will see the balance increase in your wallet, you will not see an accompanying transaction in your wallet’s activity or on a block explorer, since no tokens are actually being sent but instead are simply being rebased.
### **How often do you rebase rOUSG?**[](https://docs.ondo.finance/qualified-access-products/ousg/rebasing#how-often-do-you-rebase-rousg)
We aim to rebase every Business Day based on the net income received the previous Business Day.
In the event that we are unable to update the price or rebase on a given Business Day, investors holding their tokens will still receive the yield from the ‘missed’ day at the time of the next update. Note that tokenholders who submit a redemption request prior to a price update or rebase on a given day are not paid yield on those tokens for that day. Please also note yield is paid to the holder of the tokens at the time of update; if you have already transferred or redeemed your tokens, you will not receive yield on them. Note that OUSG holders are not ‘paid out’ yield per se; instead, that yield is reinvested into fund, thereby increasing the value of their _existing_ OUSG tokens.
### What is the difference between rebasing rOUSG and updating the OUSG token price onchain?[](https://docs.ondo.finance/qualified-access-products/ousg/rebasing#what-is-the-difference-between-rebasing-rousg-and-updating-the-ousg-token-price-onchain)
When we update the OUSG token price (aka Net Asset Value, aka NAV) in the [OUSG Price Oracle (opens in a new tab)](https://docs.ondo.finance/addresses)
this automatically triggers a rebase to occur in the same block, so you can think of a “price update” and a “rebase” as de facto being the same thing and happening at the same time.
### How do I convert between OUSG and rOUSG?[](https://docs.ondo.finance/qualified-access-products/ousg/rebasing#how-do-i-convert-between-ousg-and-rousg)
You can easily convert between OUSG and rOUSG using the ‘convert’ option on the [OUSG product page (opens in a new tab)](https://ondo.finance/ousg)
on our website.
[OUSG vs Rebasing OUSG (rOUSG)](https://docs.ondo.finance/qualified-access-products/ousg/ousg-vs-rebasing-ousg "OUSG vs Rebasing OUSG (rOUSG)")
[Technical](https://docs.ondo.finance/qualified-access-products/ousg/technical "Technical")
---
# Regulatory Compliance | Ondo Finance
[Qualified-Access Products](https://docs.ondo.finance/qualified-access-products)
[OUSG Token](https://docs.ondo.finance/qualified-access-products/ousg)
Regulatory Compliance
Regulatory Compliance
=====================
At Ondo, we know that legal and regulatory compliance is a critical pillar of tokenized real-world-asset offerings. We take a thorough and measured approach to risk management in general, with a compliance-oriented product design that is rooted in consultation with a variety of legal, tax, and regulatory experts.
OUSG tokens are exempt from the registration requirements of the US Securities Act of 1933, as amended (the “‘33 Act”) because they are offered and sold in reliance on Rule 506(c) of Regulation D of the 33 Act. The issuer of OUSG, Ondo I LP, is exempt from the registration requirements of the US Investment Company Act of 1940, as amended (the “‘40 Act”) because they are sold to “qualified purchasers” in relieance on Section 3(c)(7) of the 40 Act.
[Trust & Transparency](https://docs.ondo.finance/qualified-access-products/ousg/trust-and-transparency "Trust & Transparency")
[Disclaimer](https://docs.ondo.finance/qualified-access-products/ousg/disclaimer "Disclaimer")
---
# OUSG Legal Disclaimer | Ondo Finance
[Qualified-Access Products](https://docs.ondo.finance/qualified-access-products)
[OUSG Token](https://docs.ondo.finance/qualified-access-products/ousg)
Disclaimer
OUSG Legal Disclaimer
=====================
\[\*\] OUSG tokens have not been registered under the US Securities Act of 1933, as amended ("Act") or the securities or financial instrument laws of any other jurisdiction, and are available solely to accredited investors (as defined in Rule 501 of Regulation D under the Act) and qualified purchasers (as defined in Section 2(a)(51) of the US Investment Company Act of 1940, as amended). The issuer of OUSG (the “Fund”) is not registered as an investment company under the US Investment Company Act of 1940, as amended, or as an Alternative Investment Fund or Undertaking for Collective Investment in Transferable Securities in the European Economic Area, or under the securities or financial instrument laws of any other jurisdiction. The OUSG-related communications herein are not directed or intended for any investor to which OUSG is not offered.
Nothing herein constitutes any offer to sell, or any solicitation of an offer to buy, OUSG. Nothing herein constitutes investing advice. Acquiring OUSG involves risks. A OUSG holder may incur losses, including total loss of their investment. Past performance is not an indication of future results. The communications on this web page are only intended for eligible purchasers of, or for actual or potential business relationships or technical integrations with respect to, OUSG. Nothing herein constitutes investing advice. Acquiring OUSG involves risks. A OUSG holder may incur losses, including total loss of their investment. Past performance is not an indication of future results.
Ondo Capital Management LLC, the investment adviser of the Fund (“the Adviser”) is a Registered Investment Adviser registered with the U.S. Securities and Exchange Commission (“SEC”). The Adviser’s current written disclosure statement (Form ADV Part 2A) discussing its advisory services and fees is available upon request or at the SEC’s Investment Adviser Public Disclosure website ([www.adviserinfo.sec.gov (opens in a new tab)](https://adviserinfo.sec.gov/)
). Registration as an investment adviser does not imply a certain level of skill or training. The Adviser shall not be responsible for any errors or omissions, or for the results obtained from the use of the information provided by the Adviser, the Fund or any of their respective affiliates, control persons, agents or representatives.
The Token issuers, their affiliates, their respective shareholders and members, and their respective directors, officers, employees, consultants, agents and representatives (the “Ondo Persons”) do not endorse, the Ondo Persons do not make any representation or warranty whatsoever (express or implied, including but not limited to any warranty of merchantability, fitness for a particular purpose, or non-infringement) regarding, and THE ONDO PERSONS SHALL NOT HAVE ANY LIABILITY WHATSOEVER WITH RESPECT TO ANYONE'S USE OF, any third-party products, services or technologies referenced herein.
Additional terms and restrictions apply. See [docs.ondo.finance/legal/terms-of-service](https://docs.ondo.finance/legal/terms-of-service)
, [docs.ondo.finance/qualified-access-products/ousg](https://docs.ondo.finance/qualified-access-products/ousg)
, [ondo.finance/ousg (opens in a new tab)](https://ondo.finance/ousg)
, [app.ondo.finance (opens in a new tab)](https://app.ondo.finance/)
and (as applicable) the Token offering documents for details.
This communication may contain forward-looking statements, including, but not limited to, statements regarding future financial performance, business strategies, or expectations for Ondo Finance's growth and development. These statements are based on management's current expectations, estimates, projections, and beliefs, and are subject to a number of risks, uncertainties, and assumptions that could cause actual results to differ materially from those anticipated. Forward-looking statements can be identified by the use of terminology such as "may," "will," "should," "expect," "intend," "plan," "anticipate," "believe," "estimate," "predict," "potential," "continue," or the negative of these terms or other similar expressions. Factors that could cause actual results to differ materially from those contemplated by the forward-looking statements include, but are not limited to, the following: economic, competitive, legal, governmental, and technological factors affecting Ondo Finance's operations, markets, products, services, and prices. Neither Ondo Finance nor any of their respective affiliates undertakes any obligation to update or revise any forward-looking statements, whether as a result of new information, future events, or otherwise, except as required by law.
[Regulatory Compliance](https://docs.ondo.finance/qualified-access-products/ousg/regulatory-compliance "Regulatory Compliance")
[Other](https://docs.ondo.finance/qualified-access-products/ousg/other "Other")
---
# Trust & Transparency | Ondo Finance
[Qualified-Access Products](https://docs.ondo.finance/qualified-access-products)
[OUSG Token](https://docs.ondo.finance/qualified-access-products/ousg)
Trust & Transparency
Trust & Transparency
====================
### **What types of reporting or other assurances do I have that your numbers are right?**[](https://docs.ondo.finance/qualified-access-products/ousg/trust-and-transparency#what-types-of-reporting-or-other-assurances-do-i-have-that-your-numbers-are-right)
As with all of our Qualified Access Funds, our fund administrator (NAV Consulting) has direct, read-only access to all of the Fund’s accounts daily. We independently calculate the Net Asset Value of the fund each day. If ever there is a discrepancy we work with NAV Consulting to identify and correct the source of the error. Once in agreement, we publish the full set of financials created by NAV Consulting on a daily basis. Note that these reports may lag up to three days behind the price update onchain. You can find a link to those reports [here (opens in a new tab)](https://drive.google.com/drive/folders/1Ti8IzoXTibM3B2RWxystT38ISrPH-rRP?usp=sharing)
.
### **Is OUSG financially audited?**[](https://docs.ondo.finance/qualified-access-products/ousg/trust-and-transparency#is-ousg-financially-audited)
Yes. Our Qualified Access Funds are audited annually, the results of which are provided to investors.
[Technical](https://docs.ondo.finance/qualified-access-products/ousg/technical "Technical")
[Regulatory Compliance](https://docs.ondo.finance/qualified-access-products/ousg/regulatory-compliance "Regulatory Compliance")
---
# Other | Ondo Finance
[Qualified-Access Products](https://docs.ondo.finance/qualified-access-products)
[OUSG Token](https://docs.ondo.finance/qualified-access-products/ousg)
Other
Other
=====
### **What is a “Business Day”?**[](https://docs.ondo.finance/qualified-access-products/ousg/other#what-is-a-business-day)
A Business Day shall mean any day that the New York Stock Exchange is open.
### **Is OUSG a Money Market Fund?**[](https://docs.ondo.finance/qualified-access-products/ousg/other#is-ousg-a-money-market-fund)
No. A US Money Market Fund is a specific type of short-term, fixed-income mutual fund regulated under Rule 2a-7 of the Investment Company Act of 1940. Rather, OUSG is a tokenized private fund. OUSG is not, and should not be considered, a US Money Market Fund.
[Disclaimer](https://docs.ondo.finance/qualified-access-products/ousg/disclaimer "Disclaimer")
[Protocols](https://docs.ondo.finance/protocols "Protocols")
---
# Protocols | Ondo Finance
Protocols
Protocols
=========
[📄 Flux Finance\
---------------\
\
A fork of Compound v2, Flux Finance is a protocol we developed as an onchain Treasury repo marketplace, allowing users to borrow and lend stablecoins backed by high quality collateral such as OUSG (Ondo's US-Treasuries-linked token). We have since sold the protocol to the Neptune Foundation.](https://docs.ondo.finance/protocols/flux)
[Other](https://docs.ondo.finance/qualified-access-products/ousg/other "Other")
[Flux Finance](https://docs.ondo.finance/protocols/flux "Flux Finance")
---
# Flux Finance | Ondo Finance
[Protocols](https://docs.ondo.finance/protocols)
Flux Finance
Flux Finance
============
A fork of Compound v2, Flux Finance is a protocol we developed as an onchain Treasury repo marketplace, allowing users to borrow and lend stablecoins backed by high quality collateral such as OUSG (Ondo's US-Treasuries-linked token). We have since sold the protocol to the Neptune Foundation.
Find out more at [https://fluxfinance.com (opens in a new tab)](https://fluxfinance.com/)
[Protocols](https://docs.ondo.finance/protocols "Protocols")
[Developer Guides](https://docs.ondo.finance/developer-guides "Developer Guides")
---
# Developer Guides | Ondo Finance
Developer Guides
Developer Guides
================
These guides are crafted to provide a clear understanding of the unique features of Ondo Products and the recommended practices for integrating with or building upon our protocol.
Should you find any unanswered questions, outdated information, or if you require additional development support, feel free to reach out to us at [support@ondo.finance](mailto:support@ondo.finance)
. We are here to support you.
[📄 Integration Guidelines for Protocols Supporting USDY on Mantle\
-----------------------------------------------------------------\
\
USDY exists in two forms on Mantle. USDY is the accumulating form, and mUSD is the distributing form.](https://docs.ondo.finance/tools/converter/usdy-musd-conversion)
[Flux Finance](https://docs.ondo.finance/protocols/flux "Flux Finance")
[Integration Guidelines for Protocols Supporting USDY on Mantle](https://docs.ondo.finance/developer-guides/mantle-integration-guidelines "Integration Guidelines for Protocols Supporting USDY on Mantle")
---
# Ondo Token Tools (Bridge and Converter) | Ondo Finance
Ondo Token Tools (Bridge and Converter)
Ondo Token Tools (Bridge and Converter)
=======================================
[📄 Ondo Token Bridge\
--------------------\
\
Introduction](https://docs.ondo.finance/tools/ondo-bridge)
[🗃️ Ondo Token Converter\
------------------------](https://docs.ondo.finance/tools/converter)
[Integration Guidelines for Protocols Supporting USDY on Mantle](https://docs.ondo.finance/developer-guides/mantle-integration-guidelines "Integration Guidelines for Protocols Supporting USDY on Mantle")
[Ondo Token Bridge](https://docs.ondo.finance/tools/ondo-bridge "Ondo Token Bridge")
---
# Ondo Token Bridge | Ondo Finance
[Ondo Token Tools (Bridge and Converter)](https://docs.ondo.finance/tools)
Ondo Token Bridge
Ondo Token Bridge
=================
Introduction[](https://docs.ondo.finance/tools/ondo-bridge#introduction)
-------------------------------------------------------------------------
We have partnered with LayerZero, the leading interoperability protocol that has successfully transmitted over 135 million messages and facilitated the exchange of more than $60 billion in value. The integration of LayerZero V2 alongside our enhanced security measures delivers premier security for our users, all while maintaining a seamless user experience.
Every aspect of this bridge is developed with security in mind:
* We’ve carefully selected a set of off-chain verifiers (a.k.a. DVNs), which guarantee strong security through independent actors (minimizing collusion risk) and disparate verification mechanisms (ensuring that even if a bug were to exist in one verifier, that verifier’s actions are mutually exclusive to the others and cannot compromise the overall system).
* We have worked with LayerZero to develop a custom rate limiting implementation and emergency pause feature.
* We have worked closely with a leading Web3 security firm and LayerZero Labs to vet all aspects of the configuration.
LayerZero Mechanism[](https://docs.ondo.finance/tools/ondo-bridge#layerzero-mechanism)
---------------------------------------------------------------------------------------
At a high level, the LayerZero protocol is a mechanism to securely transmit messages across blockchains.
Decentralized Verification Networks (DVNs) monitor for bridging events from source blockchains, validate these transactions, then post attestations to the destination chains. An executor submits a payload to the destination chain; if the executor's payload and the DVN attestations match, the USDY or GM tokens are minted to the recipient.
Ondo has employed LayerZero’s OFT (Omnichain Fungible Token) standard to allow users to burn and mint **native USDY and GM tokens** on all supported chains.
GM assets also use the OFT architecture, but with a custom unified multi-asset configuration allowing all GM tokens to be bridged through a unified framework instead of relying on separate bridge configurations for every token on every chain.
DVN Selections[](https://docs.ondo.finance/tools/ondo-bridge#dvn-selections)
-----------------------------------------------------------------------------
Our implementation of the OFT Token Bridge leverages the following independent verification mechanisms as DVNs to provide multiple redundant levels of security:
* Canary DVN
* LayerZero Labs DVN
* Ondo DVN
Our custom Ondo DVN was built with unique validation specifically for bridging USDY and GM tokens.
Chain Availability[](https://docs.ondo.finance/tools/ondo-bridge#chain-availability)
-------------------------------------------------------------------------------------
### USDY[](https://docs.ondo.finance/tools/ondo-bridge#usdy)
We currently support USDY transfers between Arbitrum, Ethereum, Mantle, and Solana. Stay tuned for more chain integrations coming soon.
### Global Markets (GM)[](https://docs.ondo.finance/tools/ondo-bridge#global-markets-gm)
We currently support GM token transfers between Ethereum and BNB Chain. Stay tuned for more chain integrations coming soon.
Rate Limiting[](https://docs.ondo.finance/tools/ondo-bridge#rate-limiting)
---------------------------------------------------------------------------
The bridge implementations contain a built-in rate limit feature in the smart contracts, enforcing both an outbound and an inbound limit. The capacity of the rate limiter refills at a linear rate, and blockchain transactions attempting to exceed the rate limit capacity will revert. This security measure enforces an upper bound on the amount that can be transferred per-pathway over a (configurable) 24 hour period.
### USDY[](https://docs.ondo.finance/tools/ondo-bridge#usdy-1)
#### EVM ↔ EVM (Arbitrum, Ethereum, Mantle)[](https://docs.ondo.finance/tools/ondo-bridge#evm--evm-arbitrum-ethereum-mantle)
* The **outbound** limit is **450,000 USDY** per pathway per day.
* The **inbound** limit is **500,000 USDY** per pathway per day.
#### Solana ↔ EVM (Arbitrum, Ethereum, Mantle)[](https://docs.ondo.finance/tools/ondo-bridge#solana--evm-arbitrum-ethereum-mantle)
* The **outbound** limit is **250,000 USDY** per pathway per day.
* The **inbound** limit is **300,000 USDY** per pathway per day.
### Global Markets (GM)[](https://docs.ondo.finance/tools/ondo-bridge#global-markets-gm-1)
GM transfers are currently supported between Ethereum and BNB chain, and are rate-limited separately from USDY:
* Approximately $450,000 per day, per GM asset, per direction
* Limits apply to each individual asset (e.g., AAPLon, NVDAon, SPYon)
_Note: DVN and rate limit configurations are subject to change by Ondo Finance with the ever-evolving bridging landscape._
FAQ[](https://docs.ondo.finance/tools/ondo-bridge#faq)
-------------------------------------------------------
### Can I specify a different destination address for my transfer?[](https://docs.ondo.finance/tools/ondo-bridge#can-i-specify-a-different-destination-address-for-my-transfer)
Yes - Ondo’s bridge webpage allows the user to specify a different destination address.
* First, click the edit (pencil) icon next to the address in the Receive section.

* Next, input the desitnation address and click Confirm Address.

### Are there any fees associated with transferring tokens?[](https://docs.ondo.finance/tools/ondo-bridge#are-there-any-fees-associated-with-transferring-tokens)
Transferring tokens comes at no fee on the USDY or GM token amount — you’ll receive the same amount of tokens on the destination chain as you’re sending from the source chain.
However, there are two types of fees paid in the native token of the source chain (such as ETH):
1. **Standard gas fees:** You will pay for the normal gas cost to publish the transaction to the source chain, just like you would for any other transaction. This is handled automatically by your wallet.
2. **Cross-chain gas fees:** Both LayerZero and the DVNs will receive gas fees for publishing your transaction to the destination chain. This is shown under **Cross-chain Fee** in the Order Summary section.

### How long do transfers take?[](https://docs.ondo.finance/tools/ondo-bridge#how-long-do-transfers-take)
Transactions take between 1 and 30 minutes to complete depending on the selected chain path. The tokens will automatically be sent to the recipient wallet on the destination chain.
In cases of network congestion, this may be delayed up to 24 hours.
### Are there any bridging best practices?[](https://docs.ondo.finance/tools/ondo-bridge#are-there-any-bridging-best-practices)
When bridging tokens across blockchains, it's highly recommended to perform a small test transfer before committing to a larger transaction. This allows you to verify that the bridge is functioning correctly, confirm that you're using the right address and blockchain network, and ensure any fees or delays are clearly understood. Test transfers reduce the risk of potential loss or issues caused by misconfiguration or unforeseen problems during cross-chain transfers.
### My transaction is pending or has failed. What should I do?[](https://docs.ondo.finance/tools/ondo-bridge#my-transaction-is-pending-or-has-failed-what-should-i-do)
In most cases, you can resolve this on your own.
**Check LayerZero Scan**
1. Check the status on the LayerZero explorer. Paste your source chain transaction hash into the search bar at [https://layerzeroscan.com (opens in a new tab)](https://layerzeroscan.com/)
.
2. On the right-hand side of the page, there may be an **Execute** button. Click this, and connect your wallet.

3. In the provided window, click **Commit and execute**.

If you are unable to resolve the issue and the transfer has not processed after 24 hours, please contact us at [support@ondo.finance](mailto:support@ondo.finance)
.
[Ondo Token Tools (Bridge and Converter)](https://docs.ondo.finance/tools "Ondo Token Tools (Bridge and Converter)")
[Ondo Token Converter](https://docs.ondo.finance/tools/converter "Ondo Token Converter")
---
# Integration Guidelines for Protocols Supporting USDY on Mantle | Ondo Finance
[Developer Guides](https://docs.ondo.finance/developer-guides)
Integration Guidelines for Protocols Supporting USDY on Mantle
Integration Guidelines for Protocols Supporting USDY on Mantle
==============================================================
**USDY & mUSD**[](https://docs.ondo.finance/developer-guides/mantle-integration-guidelines#usdy--musd)
-------------------------------------------------------------------------------------------------------
### USDY[](https://docs.ondo.finance/developer-guides/mantle-integration-guidelines#usdy)
**USDY (US Dollar Yield Token)**: USDY is a tokenized note secured by short-term US Treasuries and bank demand deposits. USDY holders receive yield generated from the underlying assets in the form of increasing redemption value (accumulating token). USDY contract is an upgradeable (Transparent Upgradeable Proxy) ERC-20 token. To hold, send, and receive USDY, users should not be on the [blocklist (opens in a new tab)](https://github.com/code-423n4/2023-09-ondo/blob/main/contracts/usdy/blocklist/Blocklist.sol)
.
### mUSD[](https://docs.ondo.finance/developer-guides/mantle-integration-guidelines#musd)
**mUSD** is the rebasing version of USDY, maintaining a consistent peg to $1. Interest is distributed via new token units. Users can swap freely between USDY and mUSD. A swapper UI will be available in October on [ondo.finance (opens in a new tab)](https://ondo.finance/)
.
mUSD is heavily based on other rebasing tokens such as `stETH`. Users can acquire mUSD tokens by calling the `wrap(uint256)` function on the contract. While the price of a single USDY token increases over time, the price of a single mUSD token is fixed at a price of 1 Dollar, with yield being accrued in the form of additional mUSD tokens. Similarly when a user wishes to convert their `mUSD` to `USDY` they can call the `unwrap(uint256)` function, and receive their corresponding amount of `USDY`.
In order to determine the USD value of the USDY locked in the contract, mUSD will call into `RWADynamicRateOracle.sol` in order to fetch the current price.
Because `mUSD` is the rebasing variant of `USDY` the same transfer restrictions for `USDY` are also applied to the `mUSD` token in the `beforeTransfer(address,address,uint256)` hook.
`mUSD` rebases daily at 12:00am GMT.
USDY Oracle (**RWADynamicRateOracle)**[](https://docs.ondo.finance/developer-guides/mantle-integration-guidelines#usdy-oracle-rwadynamicrateoracle)
----------------------------------------------------------------------------------------------------------------------------------------------------
The RWADynamicRateOracle contract is used to post price evolution for USDY on chain. This contract accepts a [`Range` (opens in a new tab)](https://github.com/code-423n4/2023-09-ondo/blob/main/contracts/rwaOracles/RWADynamicOracle.sol#L295)
as input from a trusted admin, and will apply the following conversion to the `lastSetPrice` for a given range:
currentPrice = (Range.dailyInterestRate ** (Days Elapsed + 1)) * Range.lastSetPrice
There is a functionality within the contract that if a range has elapsed and there is no subsequent range set, the oracle will return the maximum price of the previous range for all `block.timestamp` > `Range.end`
Integrating USDY into Your Web3 Application[](https://docs.ondo.finance/developer-guides/mantle-integration-guidelines#integrating-usdy-into-your-web3-application)
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
As users may hold USDY or mUSD, a good practice is to support both.
Let's assume a user holds mUSD and wants to supply to your USDY pool.
### Option 1: Native integration[](https://docs.ondo.finance/developer-guides/mantle-integration-guidelines#option-1-native-integration)
The user can directly use his mUSD to interact with your contracts. This means that your contracts will add an extra call to swap from mUSD to USDY before depositing the USDY in the pool.
Example of a native integration: [Compound pool on curve.fi (opens in a new tab)](https://curve.fi/#/ethereum/pools/compound/deposit)

The user can deposit stables (unwrapped)

...or stables lent into Compound (wrapped)
### Option 2: Informative integration[](https://docs.ondo.finance/developer-guides/mantle-integration-guidelines#option-2-informative-integration)
When trying to supply mUSD, your app informs the user they need to swap to USDY before depositing to the pool: “To supply USDY, you must first swap your mUSD for USDY at [ondo.finance (opens in a new tab)](https://ondo.finance/)
”
Example of an informative integration: [wstETH on Balancer (opens in a new tab)](https://app.balancer.fi/#/ethereum/pool/0x93d199263632a4ef4bb438f1feb99e57b4b5f0bd0000000000000000000005c2/add-liquidity)

The user is informed on how to wrap/unwrap
SmartContracts details[](https://docs.ondo.finance/developer-guides/mantle-integration-guidelines#smartcontracts-details)
--------------------------------------------------------------------------------------------------------------------------
* **[rUSDY.sol (opens in a new tab)](https://github.com/code-423n4/2023-09-ondo/blob/main/contracts/usdy/rUSDY.sol)
** - This contract serves as the backbone for an interest-bearing token where users can `wrap and unwrap` their `USDY` tokens to earn interest. It also includes features for access control and address management.
* **[rUSDYFactory.sol (opens in a new tab)](https://github.com/code-423n4/2023-09-ondo/blob/main/contracts/usdy/rUSDYFactory.sol)
** - This is a factory contract that allows the deployment of upgradable instances of the `mUSD token` contract. It is managed by a guardian address, and the deployment process involves creating an implementation contract, a proxy admin contract, and a proxy contract for the token. The code is designed to facilitate the upgradeability of the `mUSD` token and includes functions for batched external calls.
* **[RWADynamicOracle.sol (opens in a new tab)](https://github.com/code-423n4/2023-09-ondo/blob/main/contracts/rwaOracles/RWADynamicOracle.sol)
** - This contract is a dynamic Oracle that provides the price of `USDY` based on configured time ranges and daily interest rates. It also includes mechanisms for pausing and access control to manage the ranges and contract operation.
* **[IRWADynamicOracle (opens in a new tab)](https://github.com/code-423n4/2023-09-ondo/blob/main/contracts/rwaOracles/IRWADynamicOracle.sol)
** - This is an interface that sets a standard for any contract wishing to provide information about the price of `RWA` (Asset-Backed Real World Assets) or similar assets. Contracts that implement this interface must provide a `getPrice()` function that returns the current price of `RWA`. The interface does not contain implementation logic but simply establishes a common structure for communication with dynamic asset price oracles.
Resources[](https://docs.ondo.finance/developer-guides/mantle-integration-guidelines#resources)
------------------------------------------------------------------------------------------------
* [Media Kit (opens in a new tab)](https://www.notion.so/3bc0a5aced014cc4b0ef62f1638bbf8e?pvs=21)
* [Contract addresses](https://docs.ondo.finance/addresses)
* [Audits](https://docs.ondo.finance/audits)
* [USDY github repository (opens in a new tab)](https://github.com/ondoprotocol/usdy)
* * *
**USDY Legal Disclaimer**
_USDY tokens have not been registered under the US Securities Act of 1933, as amended ("Act") or the securities or financial instrument laws of any other jurisdiction, and may not be offered or sold in the US or to US persons unless registered under the Act or an exemption from the registration requirements thereof is available. The Tokens are offered and sold in the European Economic Area and the United Kingdom solely to qualified investors, and in Switzerland solely to professional clients. Other jurisdiction-based prohibitions and restrictions apply. Ondo Global Markets (BVI) Limited, the issuer of USDY, is not registered as an investment company under the US Investment Company Act of 1940, as amended, or as an Alternative Investment Fund or Undertaking for Collective Investment in Transferable Securities in the European Economic Area, or under the securities or financial instrument laws of any other jurisdiction. Nothing herein constitutes any offer to sell, or any solicitation of an offer to buy, USDY. Nothing herein constitutes investing advice. Acquiring USDY involves risks. A USDY holder may incur losses, including total loss of their purchase price. Past performance is not an indication of future results. Additional terms apply. See [docs.ondo.finance/legal/terms-of-service](https://docs.ondo.finance/legal/terms-of-service)
, [docs.ondo.finance/general-access-products/usdy](https://docs.ondo.finance/general-access-products/usdy)
and [ondo.finance/usdy (opens in a new tab)](https://ondo.finance/usdy)
for details._
[Developer Guides](https://docs.ondo.finance/developer-guides "Developer Guides")
[Ondo Token Tools (Bridge and Converter)](https://docs.ondo.finance/tools "Ondo Token Tools (Bridge and Converter)")
---
# Ondo Token Converter | Ondo Finance
[Ondo Token Tools (Bridge and Converter)](https://docs.ondo.finance/tools)
Ondo Token Converter
Ondo Token Converter
====================
Most Ondo tokens are yield-bearing. This yield can be paid out either in a distributing form or in an accumulating form.
For distributing tokens, the yield accrues daily via additional tokens distributed to your wallet. The redemption value per token stays stable at $1, and the amount of tokens in your wallet increases.
For accumulating tokens, the yield accrues daily via an increasing redemption value per token. The quantity of tokens in your wallet remains the same, but the redemption value per token has increased.
You can convert anytime between these two forms with no slippage using the Ondo Token Converter.
[📄 USDY and mUSD Conversion\
---------------------------\
\
USDY exists in two forms on Mantle. USDY is the accumulating form, and mUSD is the distributing form.](https://docs.ondo.finance/tools/converter/usdy-musd-conversion)
[Ondo Token Bridge](https://docs.ondo.finance/tools/ondo-bridge "Ondo Token Bridge")
[USDY and mUSD Conversion](https://docs.ondo.finance/tools/converter/usdy-musd-conversion "USDY and mUSD Conversion")
---
# USDY and mUSD Conversion | Ondo Finance
[Ondo Token Tools (Bridge and Converter)](https://docs.ondo.finance/tools)
[Ondo Token Converter](https://docs.ondo.finance/tools/converter)
USDY and mUSD Conversion
USDY and mUSD Conversion
========================
What is the difference between USDY and mUSD?
=============================================
USDY exists in two forms on Mantle. USDY is the accumulating form, and mUSD is the distributing form.
* USDY: an accumulating ERC-20 token with a redemption value that increases daily.
* mUSD: a distributing ERC-20 token pegged to $1. mUSD holders automatically receive their yield in their wallet via additional mUSD tokens.
Users receive the same amount of interest regardless of the token they hold.
Users can convert anytime from USDY to mUSD and from mUSD to USDY using the Ondo Token Converter.
How can I convert between USDY and mUSD?
========================================
Convert from the Ondo Finance website[](https://docs.ondo.finance/tools/converter/usdy-musd-conversion#convert-from-the-ondo-finance-website)
----------------------------------------------------------------------------------------------------------------------------------------------
You can use the Ondo Token Converter on [ondo.finance/convert (opens in a new tab)](http://ondo.finance/convert)
, where you can connect your wallet and convert your USDY to mUSD and vice-versa.
Convert from the Mantle Explorer[](https://docs.ondo.finance/tools/converter/usdy-musd-conversion#convert-from-the-mantle-explorer)
------------------------------------------------------------------------------------------------------------------------------------
You will need to interact with two contracts:
* [USDY (opens in a new tab)](https://explorer.mantle.xyz/address/0x5bE26527e817998A7206475496fDE1E68957c5A6/contracts?contract-tab=read-proxy#address-tabs)
* [mUSD (opens in a new tab)](https://explorer.mantle.xyz/address/0xab575258d37EaA5C8956EfABe71F4eE8F6397cF3/contracts?contract-tab=write-proxy#address-tabs)
### From USDY to mUSD[](https://docs.ondo.finance/tools/converter/usdy-musd-conversion#from-usdy-to-musd)
This is a two-transaction process.
**First transaction: Approve mUSD to spend your USDY**
Open the [USDY address in the Mantle explorer (opens in a new tab)](https://explorer.mantle.xyz/address/0x5bE26527e817998A7206475496fDE1E68957c5A6)
.
* 
Click on Contract
* 
Click on Write Proxy
* 
Identify the ‘approve’ function, and expand it
* 
Insert 0xab575258d37EaA5C8956EfABe71F4eE8F6397cF3 in the spender address. This is the mUSD token address
* 
Insert the amount of USDY you wish to convert to mUSD, and click on the 10^18 button. In this example, 1 USDY is about to be converted to mUSD
* 
Click on Write. You will be prompted to connect your wallet, and sign a transaction
* 
Once the transaction signed, you will see a Success message
**Second transaction: Convert USDY to mUSD**
* Open the [mUSD address in the Mantle Explorer (opens in a new tab)](https://explorer.mantle.xyz/address/0xab575258d37EaA5C8956EfABe71F4eE8F6397cF3/)
.
* Similarly to the previous step, click on ‘Contract’, and ‘Write Proxy’.
* Scroll down to identify and expand the wrap function.
* Insert the amount of tokens you wish to convert to mUSD, and click on the 10^18 button.
* 
Click Write to sign the transaction (your wallet should already be connected to the explorer)
* 
After confirming in your wallet, you can open the transaction hash in the explorer, and observe the amount of mUSD you received
### From mUSD to USDY[](https://docs.ondo.finance/tools/converter/usdy-musd-conversion#from-musd-to-usdy)
Open the [mUSD address in the Mantle Explorer (opens in a new tab)](https://explorer.mantle.xyz/address/0xab575258d37EaA5C8956EfABe71F4eE8F6397cF3/)
.
* 
Click on Contract
* 
Click on Write Proxy
* 
Scroll down to identify the ‘unwrap’ function
* 
Insert the amount of mUSD you wish to convert to USDY, and click on the 10^18 button. In this example, 1 mUSD is about to be converted to USDY
* 
Click on Write. You will be prompted to connect your wallet and sign a transaction
* 
Once the transaction is signed, you will see a Success message
* 
Clicking on the transaction link shows you the amount of USDY that you received in your wallet. In this example, 1 mUSD got converted to 0.9882 USDY
[Ondo Token Converter](https://docs.ondo.finance/tools/converter "Ondo Token Converter")
[Smart Contract Addresses](https://docs.ondo.finance/addresses "Smart Contract Addresses")
---
# Legal | Ondo Finance
Legal
Legal
=====
[📄 Terms of Service\
-------------------\
\
Last Updated: November 2023](https://docs.ondo.finance/legal/terms-of-service)
[📄 Privacy Policy\
-----------------\
\
Last Updated: January 2023](https://docs.ondo.finance/legal/privacy-policy)
[📄 Cookies Policy\
-----------------\
\
Last Updated: January 2023](https://docs.ondo.finance/legal/cookies-policy)
[📄 Disclaimers\
--------------\
\
Last Updated: January 2023](https://docs.ondo.finance/legal/disclaimers)
[Ondo V1 - Vaults & LaaS](https://docs.ondo.finance/ondo-v1-vaults-laas "Ondo V1 - Vaults & LaaS")
[Terms of Service](https://docs.ondo.finance/legal/terms-of-service "Terms of Service")
---
# Smart Contract Addresses | Ondo Finance
Smart Contract Addresses
Smart Contract Addresses
========================
OUSG[](https://docs.ondo.finance/addresses#ousg)
-------------------------------------------------
### Ethereum[](https://docs.ondo.finance/addresses#ethereum)
| Contract/address name | Address | Source code | Description |
| --- | --- | --- | --- |
| OUSG | [`0x1B19C19393e2d034D8Ff31ff34c81252FcBbee92` (opens in a new tab)](https://etherscan.io/token/0x1B19C19393e2d034D8Ff31ff34c81252FcBbee92) | [Github (opens in a new tab)](https://github.com/ondoprotocol/tokenized-funds/blob/main/contracts/token/CashKYCSenderReceiver.sol) | The OUSG token |
| rOUSG | [`0x54043c656F0FAd0652D9Ae2603cDF347c5578d00` (opens in a new tab)](https://etherscan.io/token/0x54043c656F0FAd0652D9Ae2603cDF347c5578d00) | [Etherscan (opens in a new tab)](https://etherscan.io/address/0x54043c656F0FAd0652D9Ae2603cDF347c5578d00#code) | The rOUSG token (rebasing OUSG) |
| OUSG\_InstantManager | [`0x93358db73B6cd4b98D89c8F5f230E81a95c2643a` (opens in a new tab)](https://etherscan.io/address/0x93358db73B6cd4b98D89c8F5f230E81a95c2643a) | [Etherscan (opens in a new tab)](https://etherscan.io/address/0x93358db73B6cd4b98D89c8F5f230E81a95c2643a#code) | The Ondo smart contract investors use on the ondo.finance webapp to instantly buy or redeem OUSG |
| Coinbase Prime address (ousg.eth) | [`0xF67416a2C49f6A46FEe1c47681C5a3832cf8856c` (opens in a new tab)](https://etherscan.io/address/0xF67416a2C49f6A46FEe1c47681C5a3832cf8856c) | N/A | Coinbase Prime custodian account. Investors can buy OUSG by transferring USDC to this address or by using the web app hosted on ondo.finance, where the CashManager will transfer USDC to this address on their behalf. |
| OndoIDRegistry | [`0xcf6958D69d535FD03BD6Df3F4fe6CDcd127D97df` (opens in a new tab)](https://etherscan.io/address/0xcf6958D69d535FD03BD6Df3F4fe6CDcd127D97df) | [Etherscan (opens in a new tab)](https://etherscan.io/address/0xcf6958D69d535FD03BD6Df3F4fe6CDcd127D97df#code) | Addresses that can hold OUSG are stored via this contract |
| OndoOracle | [`0x9Cad45a8BF0Ed41Ff33074449B357C7a1fAb4094` (opens in a new tab)](https://etherscan.io/address/0x9Cad45a8BF0Ed41Ff33074449B357C7a1fAb4094) | [Etherscan (opens in a new tab)](https://etherscan.io/address/0x9Cad45a8BF0Ed41Ff33074449B357C7a1fAb4094#code) | Unified interface for retrieving token price data required by Ondo contracts. |
| OUSG Recipient | [`0x72Be8C14B7564f7a61ba2f6B7E50D18DC1D4B63D` (opens in a new tab)](https://etherscan.io/address/0x72Be8C14B7564f7a61ba2f6B7E50D18DC1D4B63D) | [Etherscan (opens in a new tab)](https://etherscan.io/address/0x72Be8C14B7564f7a61ba2f6B7E50D18DC1D4B63D#code) | Recipient address for OUSG, for manual redemptions. |
| PYUSD Recipient | [`0x0317a350b093F8010837d1b844292555d73ebC2c` (opens in a new tab)](https://etherscan.io/address/0x0317a350b093F8010837d1b844292555d73ebC2c) | [Etherscan (opens in a new tab)](https://etherscan.io/address/0x0317a350b093F8010837d1b844292555d73ebC2c#code) | Recipient address for PYUSD, for manual subscriptions. |
### Polygon[](https://docs.ondo.finance/addresses#polygon)
| Contract/address name | Address | Source code | Description |
| --- | --- | --- | --- |
| OUSG | [`0xbA11C5effA33c4D6F8f593CFA394241CfE925811` (opens in a new tab)](https://polygonscan.com/token/0xbA11C5effA33c4D6F8f593CFA394241CfE925811) | [PolygonScan (opens in a new tab)](https://polygonscan.com/address/0xbA11C5effA33c4D6F8f593CFA394241CfE925811#code) | The OUSG token |
| CashManager | [`0x6B7443808ACFCD48f1DE212C2557462fA86Ee945` (opens in a new tab)](https://polygonscan.com/address/0x6B7443808ACFCD48f1DE212C2557462fA86Ee945) | [PolygonScan (opens in a new tab)](https://polygonscan.com/address/0x6B7443808ACFCD48f1DE212C2557462fA86Ee945#code) | The Ondo smart contract investors use on the ondo.finance webapp to buy or redeem OUSG |
| Registry | [`0x7cD852c0D7613aA869e632929560f310D4059AC1` (opens in a new tab)](https://polygonscan.com/address/0x7cD852c0D7613aA869e632929560f310D4059AC1) | [PolygonScan (opens in a new tab)](https://polygonscan.com/address/0x7cD852c0D7613aA869e632929560f310D4059AC1#code) | Addresses that can hold OUSG are stored via this contract |
### Solana[](https://docs.ondo.finance/addresses#solana)
| Contract/address name | Address | Source code | Description |
| --- | --- | --- | --- |
| OUSG | [`i7u4r16TcsJTgq1kAG8opmVZyVnAKBwLKu6ZPMwzxNc` (opens in a new tab)](https://solscan.io/token/i7u4r16TcsJTgq1kAG8opmVZyVnAKBwLKu6ZPMwzxNc) | N/A | The OUSG token on Solana |
| OUSG Circle address | [`EgFDCr2UmsoUvoJ5DcNZqVnkFZsDE9KyCYBhGcnrAd5G` (opens in a new tab)](https://solscan.io/account/EgFDCr2UmsoUvoJ5DcNZqVnkFZsDE9KyCYBhGcnrAd5G) | N/A | Circle custodian account. Investors can buy OUSG by transferring USDC to this address. |
### XRP Ledger[](https://docs.ondo.finance/addresses#xrp-ledger)
| Contract/address name | Address | Source code | Description |
| --- | --- | --- | --- |
| OUSG | [`4F55534700000000000000000000000000000000.rHuiXXjHLpMP8ZE9sSQU5aADQVWDwv6h5p` (opens in a new tab)](https://livenet.xrpl.org/token/4F55534700000000000000000000000000000000.rHuiXXjHLpMP8ZE9sSQU5aADQVWDwv6h5p) | N/A | The OUSG token on XRP Ledger |
| OUSG Recipient | [`rHprwRkvDexV5LF5tzKQmx7U7Ku2836DA1` (opens in a new tab)](https://livenet.xrpl.org/accounts/rHprwRkvDexV5LF5tzKQmx7U7Ku2836DA1) | N/A | Recipient address for OUSG, for manual OUSG redemptions. |
| RLUSD Recipient | [`rEZiJUJskputkS6VjPAwdRLESNpdyRC6ba Destination Tag: 1` (opens in a new tab)](https://livenet.xrpl.org/accounts/rEZiJUJskputkS6VjPAwdRLESNpdyRC6ba) | N/A | Recipient address for RLUSD, for manual OUSG subscriptions. |
USDY[](https://docs.ondo.finance/addresses#usdy)
-------------------------------------------------
### Ethereum[](https://docs.ondo.finance/addresses#ethereum-1)
| Contract/address name | Address | Source code | Description |
| --- | --- | --- | --- |
| USDY | [`0x96F6eF951840721AdBF46Ac996b59E0235CB985C` (opens in a new tab)](https://etherscan.io/token/0x96F6eF951840721AdBF46Ac996b59E0235CB985C) | [Etherscan (opens in a new tab)](https://etherscan.io/address/0x96F6eF951840721AdBF46Ac996b59E0235CB985C#code) | The USDY token on Ethereum |
| rUSDY | [`0xaf37c1167910ebC994e266949387d2c7C326b879` (opens in a new tab)](https://etherscan.io/token/0xaf37c1167910ebC994e266949387d2c7C326b879) | [Etherscan (opens in a new tab)](https://etherscan.io/address/0xaf37c1167910ebC994e266949387d2c7C326b879#code) | The rUSDY token on Ethereum (rebasing USDY) |
| USDYManager | [`0x25A103A1D6AeC5967c1A4fe2039cdc514886b97e` (opens in a new tab)](https://etherscan.io/address/0x25A103A1D6AeC5967c1A4fe2039cdc514886b97e) | [Etherscan (opens in a new tab)](https://etherscan.io/address/0x25A103A1D6AeC5967c1A4fe2039cdc514886b97e#code) | The Ondo smart contract used on the ondo.finance webapp to buy or redeem USDY |
| USDY\_InstantManager | [`0xa42613C243b67BF6194Ac327795b926B4b491f15` (opens in a new tab)](https://etherscan.io/address/0xa42613C243b67BF6194Ac327795b926B4b491f15) | [Etherscan (opens in a new tab)](https://etherscan.io/address/0xa42613C243b67BF6194Ac327795b926B4b491f15#code) | The Ondo smart contract used to instantly buy or redeem USDY |
| USDYc | [`0xe86845788d6e3e5c2393ade1a051ae617d974c09` (opens in a new tab)](https://etherscan.io/token/0xe86845788d6e3e5c2393ade1a051ae617d974c09)
| [Etherscan (opens in a new tab)](https://etherscan.io/address/0xe86845788d6e3e5c2393ade1a051ae617d974c09#code)
| The USDYc token, or “Cooking USDY,” on Ethereum. An onchain bookkeeping representation of the [Temporary Global Certificate](https://docs.ondo.finance/general-access-products/usdy/how-it-works#step-3-certificate-and-usdyc-generation)
representing a lender’s rights to payment during the period before their USDY tokens are issued. When this period ends, USDY tokens are minted and the associated USDYc tokens are burned | | USDY Coinbase Prime address (USDC Deposits) | [`0xbDa73A0F13958ee444e0782E1768aB4B76EdaE28` (opens in a new tab)](https://etherscan.io/address/0xbDa73A0F13958ee444e0782E1768aB4B76EdaE28)
| N/A | Coinbase Prime custodian account. Onboarded investors can buy USDY by transferring USDC to this address or by using the web app hosted on ondo.finance, where the USDYManager will transfer USDC to this address on their behalf. | | | Redemption Price Oracle | [`0xA0219AA5B31e65Bc920B5b6DFb8EdF0988121De0` (opens in a new tab)](https://etherscan.io/address/0xa0219aa5b31e65bc920b5b6dfb8edf0988121de0)
| [Etherscan (opens in a new tab)](https://etherscan.io/address/0xa0219aa5b31e65bc920b5b6dfb8edf0988121de0#code)
| The contract that stores the current price at which USDY can be bought or redeemed from Ondo. Historical prices are also stored in the contract. | | Blocklist | [`0xd8c8174691d936E2C80114EC449037b13421B0a8` (opens in a new tab)](https://etherscan.io/address/0xd8c8174691d936E2C80114EC449037b13421B0a8)
| [Etherscan (opens in a new tab)](https://etherscan.io/address/0xd8c8174691d936E2C80114EC449037b13421B0a8#code)
| Smart contract which holds all blocked addresses |
### Mantle[](https://docs.ondo.finance/addresses#mantle)
| Contract/address name | Address | Source code | Description |
| --- | --- | --- | --- |
| USDY | [`0x5bE26527e817998A7206475496fDE1E68957c5A6` (opens in a new tab)](https://explorer.mantle.xyz/token/0x5bE26527e817998A7206475496fDE1E68957c5A6) | [Mantle Explorer (opens in a new tab)](https://explorer.mantle.xyz/token/0x5bE26527e817998A7206475496fDE1E68957c5A6?tab=contract) | The USDY token on Mantle |
| Mantle USD (mUSD) | [`0xab575258d37EaA5C8956EfABe71F4eE8F6397cF3` (opens in a new tab)](https://explorer.mantle.xyz/token/0xab575258d37EaA5C8956EfABe71F4eE8F6397cF3) | [Mantle Explorer (opens in a new tab)](https://explorer.mantle.xyz/token/0xab575258d37EaA5C8956EfABe71F4eE8F6397cF3?tab=contract) | The rebasing counterpart of USDY on Mantle |
| Redemption Price Oracle | [`0xA96abbe61AfEdEB0D14a20440Ae7100D9aB4882f` (opens in a new tab)](https://explorer.mantle.xyz/address/0xA96abbe61AfEdEB0D14a20440Ae7100D9aB4882f) | [Mantle Explorer (opens in a new tab)](https://explorer.mantle.xyz/address/0xA96abbe61AfEdEB0D14a20440Ae7100D9aB4882f?tab=contract) | The contract that stores the current price at which USDY can be bought or redeemed from Ondo. Historical prices are also stored in the contract. |
| Blocklist | [`0xdBd7a7d8807f0C98c9A58f7732f2799c8587e5c6` (opens in a new tab)](https://explorer.mantle.xyz/address/0xdBd7a7d8807f0C98c9A58f7732f2799c8587e5c6) | [Mantle Explorer (opens in a new tab)](https://explorer.mantle.xyz/address/0xdBd7a7d8807f0C98c9A58f7732f2799c8587e5c6?tab=contract) | Smart contract which holds all blocked addresses |
### Solana[](https://docs.ondo.finance/addresses#solana-1)
| Contract/address name | Address | Source code | Description |
| --- | --- | --- | --- |
| USDY | [`A1KLoBrKBde8Ty9qtNQUtq3C2ortoC3u7twggz7sEto6` (opens in a new tab)](https://solscan.io/token/A1KLoBrKBde8Ty9qtNQUtq3C2ortoC3u7twggz7sEto6) | N/A | The USDY token on Solana |
### Sui[](https://docs.ondo.finance/addresses#sui)
| Contract/address name | Address | Source code | Description |
| --- | --- | --- | --- |
| USDY | [`0x960b531667636f39e85867775f52f6b1f220a058c4de786905bdf761e06a56bb::usdy::USDY` (opens in a new tab)](https://suiscan.xyz/mainnet/coin/0x960b531667636f39e85867775f52f6b1f220a058c4de786905bdf761e06a56bb::usdy::USDY) | [Suiscan (opens in a new tab)](https://suiscan.xyz/mainnet/object/0x960b531667636f39e85867775f52f6b1f220a058c4de786905bdf761e06a56bb/contracts) | The USDY token on Sui |
### Aptos[](https://docs.ondo.finance/addresses#aptos)
| Contract/address name | Address | Source code | Description |
| --- | --- | --- | --- |
| USDY | [`0xcfea864b32833f157f042618bd845145256b1bf4c0da34a7013b76e42daa53cc::usdy::USDY` (opens in a new tab)](https://explorer.aptoslabs.com/account/0xcfea864b32833f157f042618bd845145256b1bf4c0da34a7013b76e42daa53cc) | [Aptos Explorer (opens in a new tab)](https://explorer.aptoslabs.com/account/0xcfea864b32833f157f042618bd845145256b1bf4c0da34a7013b76e42daa53cc/modules/code/usdy?network=mainnet) | The USDY token on Aptos |
| USDY Redemptions Account | [`0xcfea864b32833f157f042618bd845145256b1bf4c0da34a7013b76e42daa53cc` (opens in a new tab)](https://explorer.aptoslabs.com/account/0xcfea864b32833f157f042618bd845145256b1bf4c0da34a7013b76e42daa53cc) | N/A | Address for USDY Redemptions on Aptos |
### Noble[](https://docs.ondo.finance/addresses#noble)
| Contract/address name | Address | Source code | Description |
| --- | --- | --- | --- |
| USDY | [`ausdy` (opens in a new tab)](https://www.mintscan.io/noble/assets/native/YXVzZHk=) | [Github (opens in a new tab)](https://github.com/ondoprotocol/usdy-noble) | The USDY token on Noble (Cosmos ecosystem) |
| USDY Redemptions Account | [`noble15r2wn80pqqnmq9csfd24t0s3q9lfyfx2dh5yu3` (opens in a new tab)](https://www.mintscan.io/noble/address/noble15r2wn80pqqnmq9csfd24t0s3q9lfyfx2dh5yu3) | N/A | Address for USDY Redemptions on Noble |
### Arbitrum[](https://docs.ondo.finance/addresses#arbitrum)
| Contract/address name | Address | Source code | Description |
| --- | --- | --- | --- |
| USDY | [`0x35e050d3C0eC2d29D269a8EcEa763a183bDF9A9D` (opens in a new tab)](https://arbiscan.io/address/0x35e050d3C0eC2d29D269a8EcEa763a183bDF9A9D) | [Arbiscan Explorer (opens in a new tab)](https://arbiscan.io/address/0x35e050d3C0eC2d29D269a8EcEa763a183bDF9A9D#code) | The USDY token on Arbitrum |
### Stellar[](https://docs.ondo.finance/addresses#stellar)
| Contract/address name | Address | Source code | Description |
| --- | --- | --- | --- |
| USDY | [`USDY-GAJMPX5NBOG6TQFPQGRABJEEB2YE7RFRLUKJDZAZGAD5GFX4J7TADAZ6` (opens in a new tab)](https://stellar.expert/explorer/public/asset/USDY-GAJMPX5NBOG6TQFPQGRABJEEB2YE7RFRLUKJDZAZGAD5GFX4J7TADAZ6) | N/A | The USDY token on Stellar |
| USDY Redemptions Account | [`GC5T3RH2VK3G44FIHMOZY5UGN56L52UYFGHKFUX6X2HNIGEZ2PFXMI23` (opens in a new tab)](https://stellar.expert/explorer/public/account/GC5T3RH2VK3G44FIHMOZY5UGN56L52UYFGHKFUX6X2HNIGEZ2PFXMI23) | N/A | Address for USDY Redemptions on Stellar |
| USDC (Stellar) Recipient | [`GALD6YYBJ5KSPEU2GUAREQLXLPUC2UJW3KZDPZPLGCBARHY5Z4NBF36T?memoId=0` (opens in a new tab)](https://stellar.expert/explorer/public/account/GALD6YYBJ5KSPEU2GUAREQLXLPUC2UJW3KZDPZPLGCBARHY5Z4NBF36T) | N/A | Recipient address for USDC on Stellar, for USDY subscriptions. |
Ondo Global Markets[](https://docs.ondo.finance/addresses#ondo-global-markets)
-------------------------------------------------------------------------------
### Ethereum[](https://docs.ondo.finance/addresses#ethereum-2)
| Contract/address name | Address | Source code | Description |
| --- | --- | --- | --- |
| GMTokenManager | [`0x2c158BC456e027b2AfFCCadF1BDBD9f5fC4c5C8c` (opens in a new tab)](https://etherscan.io/address/0x2c158BC456e027b2AfFCCadF1BDBD9f5fC4c5C8c) | [Etherscan (opens in a new tab)](https://etherscan.io/address/0x2c158BC456e027b2AfFCCadF1BDBD9f5fC4c5C8c#code) | The Ondo smart contract used to perform mints and redemptions of GM tokens (via USDC or USDon). |
| USDon | [`0xAcE8E719899F6E91831B18AE746C9A965c2119F1` (opens in a new tab)](https://etherscan.io/address/0xace8e719899f6e91831b18ae746c9a965c2119f1) | [Etherscan (opens in a new tab)](https://etherscan.io/address/0xace8e719899f6e91831b18ae746c9a965c2119f1#code) | The USDon token, which acts as the proximate token for swapping to/from GM tokens. |
| USDonManager | [`0x05CCbB4b74854f8A067b83475E8c34f5a413D7e1` (opens in a new tab)](https://etherscan.io/address/0x05CCbB4b74854f8A067b83475E8c34f5a413D7e1) | [Etherscan (opens in a new tab)](https://etherscan.io/address/0x05CCbB4b74854f8A067b83475E8c34f5a413D7e1#code) | The Ondo PSM (Peg Stability Module) smart contract for USDon, facilitating swaps between USDon and USDC. |
| GM Tokens | [`See here for GM Tokens details` (opens in a new tab)](https://docs.google.com/spreadsheets/d/1P4Q5pW5NSP5shcHysZKZ0cBnMeHAJ_XQa7nVGwN-NTY/edit?gid=0#gid=0) | [See Etherscan Contract links here (opens in a new tab)](https://docs.google.com/spreadsheets/d/1P4Q5pW5NSP5shcHysZKZ0cBnMeHAJ_XQa7nVGwN-NTY/edit?gid=0#gid=0) | Ondo Global Markets tokens |
### BNB Chain[](https://docs.ondo.finance/addresses#bnb-chain)
| Contract/address name | Address | Source code | Description |
| --- | --- | --- | --- |
| GMTokenManager | [`0x91f8Aff3738825e8eB16FC6f6b1A7A4647bDB299` (opens in a new tab)](https://bscscan.com/address/0x91f8Aff3738825e8eB16FC6f6b1A7A4647bDB299) | [BscScan (opens in a new tab)](https://bscscan.com/address/0x91f8Aff3738825e8eB16FC6f6b1A7A4647bDB299#code) | The Ondo smart contract used to perform mints and redemptions of GM tokens (via USDC or USDon). |
| USDon | [`0x1f8955E640Cbd9abc3C3Bb408c9E2E1f5F20DfE6` (opens in a new tab)](https://bscscan.com/address/0x1f8955E640Cbd9abc3C3Bb408c9E2E1f5F20DfE6) | [BscScan (opens in a new tab)](https://bscscan.com/address/0x1f8955E640Cbd9abc3C3Bb408c9E2E1f5F20DfE6#code) | The USDon token, which acts as the proximate token for swapping to/from GM tokens. |
| GM Tokens | [`See here for GM Tokens details` (opens in a new tab)](https://docs.google.com/spreadsheets/d/1P4Q5pW5NSP5shcHysZKZ0cBnMeHAJ_XQa7nVGwN-NTY/edit?gid=0#gid=0) | [See BscScan Contract links here (opens in a new tab)](https://docs.google.com/spreadsheets/d/1P4Q5pW5NSP5shcHysZKZ0cBnMeHAJ_XQa7nVGwN-NTY/edit?gid=0#gid=0) | Ondo Global Markets tokens |
Ondo Bridge[](https://docs.ondo.finance/addresses#ondo-bridge)
---------------------------------------------------------------
| Contract/address name | Address | Source code | Description |
| --- | --- | --- | --- |
| Ethereum OFT Adapter | [`0xa6275720b3fB1Efe3E6EF2b5BF2293148852307D` (opens in a new tab)](https://etherscan.io/address/0xa6275720b3fB1Efe3E6EF2b5BF2293148852307D) | [Etherscan (opens in a new tab)](https://etherscan.io/address/0xa6275720b3fB1Efe3E6EF2b5BF2293148852307D#code) | LayerZero Omnichain Fungible Token Adapter, used for handling burn and mint bridge transfers on Ethereum |
| Mantle OFT Adapter | [`0x0bE393DC46248E4285dc5CAcA3084bc7e9bfbB41` (opens in a new tab)](https://explorer.mantle.xyz/address/0x0bE393DC46248E4285dc5CAcA3084bc7e9bfbB41) | [Mantle Explorer (opens in a new tab)](https://explorer.mantle.xyz/address/0x0bE393DC46248E4285dc5CAcA3084bc7e9bfbB41?tab=contract) | LayerZero Omnichain Fungible Token Adapter, used for handling burn and mint bridge transfers on Mantle |
| Arbitrum OFT Adapter | [`0x0bE393DC46248E4285dc5CAcA3084bc7e9bfbB41` (opens in a new tab)](https://arbiscan.io/address/0x0be393dc46248e4285dc5caca3084bc7e9bfbb41) | [Arbiscan (opens in a new tab)](https://arbiscan.io/address/0x0be393dc46248e4285dc5caca3084bc7e9bfbb41#code) | LayerZero Omnichain Fungible Token Adapter, used for handling burn and mint bridge transfers on Arbitrum |
| Solana OFT Adatper | [`7YNReenG6AXgVUfmSizt6hoVXrznS4zDdgCj1UTLJ2S3` (opens in a new tab)](https://solscan.io/account/7YNReenG6AXgVUfmSizt6hoVXrznS4zDdgCj1UTLJ2S3) | N/A | LayerZero Omnichain Fungible Token Adapter, used for handling burn and mint bridge transfers on Solana |
Legacy[](https://docs.ondo.finance/addresses#legacy)
-----------------------------------------------------
The legacy contract addresses below have been deprecated and should no longer be used.
### OUSG - Ethereum[](https://docs.ondo.finance/addresses#ousg---ethereum)
| Contract/address name | Address | Source code | Description |
| --- | --- | --- | --- |
| Oracle (Legacy) | [`0x0502c5ae08E7CD64fe1AEDA7D6e229413eCC6abe` (opens in a new tab)](https://etherscan.io/address/0x0502c5ae08E7CD64fe1AEDA7D6e229413eCC6abe) | [Etherscan (opens in a new tab)](https://etherscan.io/address/0x0502c5ae08E7CD64fe1AEDA7D6e229413eCC6abe#code) | RateCheck Oracle for OUSG which holds the price for OUSG. The price can only be set +/- 74 bps relative to the price movement of the BlackRock Short-term US Treasuries (SHV) ETF. |
| OUSGInstantManager (Legacy) | [`0x2826989983e3a66F0622132D019c2Ae173eb6A43` (opens in a new tab)](https://etherscan.io/address/0x2826989983e3a66F0622132D019c2Ae173eb6A43) | [Etherscan (opens in a new tab)](https://etherscan.io/address/0x2826989983e3a66F0622132D019c2Ae173eb6A43#code) | Deprecated Ondo smart contract investors used on the ondo.finance webapp to instantly buy or redeem OUSG. Deprecated on April 7, 2025. |
| KYCRegistry (Legacy) | [`0x7cE91291846502D50D635163135B2d40a602dc70` (opens in a new tab)](https://etherscan.io/address/0x7cE91291846502D50D635163135B2d40a602dc70) | [Github (opens in a new tab)](https://github.com/ondoprotocol/tokenized-funds/blob/main/contracts/kyc/KYCRegistry.sol) | Deprecated Ondo smart contract that stored addresses that could hold OUSG. Deprecated on April 7, 2025. |
| OUSGManager (Legacy) | [`0xF16c188c2D411627d39655A60409eC6707D3d5e8` (opens in a new tab)](https://etherscan.io/address/0xF16c188c2D411627d39655A60409eC6707D3d5e8) | [Etherscan (opens in a new tab)](https://etherscan.io/address/0xF16c188c2D411627d39655A60409eC6707D3d5e8#code) | Deprecated Ondo smart contract investors used on the ondo.finance webapp to buy or redeem OUSG. Deprecated on April 15, 2024. |
| CashManager (Legacy) | [`0x3501883a646f1F8417BcB62162372550954D618f` (opens in a new tab)](https://etherscan.io/address/0x3501883a646f1F8417BcB62162372550954D618f) | [Github (opens in a new tab)](https://github.com/ondoprotocol/tokenized-funds/blob/main/contracts/CashManager.sol) | Deprecated Ondo smart contract investors used on the ondo.finance webapp to buy or redeem OUSG. Deprecated on December 13, 2023. |
[USDY and mUSD Conversion](https://docs.ondo.finance/tools/converter/usdy-musd-conversion "USDY and mUSD Conversion")
[Smart Contract Audits](https://docs.ondo.finance/audits "Smart Contract Audits")
---
# Ondo V1 - Vaults & LaaS | Ondo Finance
Ondo V1 - Vaults & LaaS
Ondo V1 — Vaults & LaaS
=======================
Ondo launched in August 2021. Its first product was Ondo Vaults, a structured finance protocol on Ethereum. These vaults enabled investors to choose between enhanced returns or downside protection when providing liquidity to decentralized exchanges like Uniswap.
Later that year, Ondo launched Liquidity-as-a-Service (LaaS), an offering that helped token issuers ramp up liquidity on decentralized exchanges. LaaS paired stablecoin issuers with DAOs issuing governance tokens to bootstrap highly-liquid AMM trading pairs. Over ten leading protocols participated in the program, including Frax, Fei (Tribe), UMA, Synapse, and NEAR.
Between Community and LaaS Vaults, Ondo facilitated over $210M in total liquidity provided (TLP).
As DeFi yields compressed in 2022, the Ondo team decided to sunset Vaults and LaaS (together, "Ondo V1") to focus on our next-generation protocols. Ondo V2, encompassing Ondo Funds and Flux Finance at launch, went live in January 2023.
The [legacy Ondo V1 website (opens in a new tab)](https://v1.ondo.finance/)
is still available for users who haven't withdrawn funds.
[Smart Contract Audits](https://docs.ondo.finance/audits "Smart Contract Audits")
[Legal](https://docs.ondo.finance/legal "Legal")
---
# Ondo Summit 2026 Terms | Ondo Finance
[Legal](https://docs.ondo.finance/legal)
Ondo Summit 2026 Terms
Ondo Summit 2026 Terms
======================
You irrevocably grant Ondo Finance Inc. and its affiliates (together, "Ondo") the right to interview, record, photograph, visually identify, or otherwise use, reproduce and edit your voice, appearance, likeness, photograph, name and/or biography, in any audio recording, video recording, or still photography captured at the February 3, 2026 Ondo Summit in New York City (collectively “Appearance and Recording”). You also irrevocably grant Ondo the right to exhibit, distribute, transmit and/or otherwise exploit your Appearance and Recording for any advertising, marketing, promotional, publicity, or other legitimate business purposes of Ondo, without having to first obtain your consent or approval. You forever release the Ondo and any of their directors, officers, employees, and agents from and against any and all claims, actions, damages, losses, costs, expenses, and liabilities of any kind, arising under any legal or equitable theory whatsoever, relating to any Appearance and Recording or any permitted use thereof.
[Disclaimers](https://docs.ondo.finance/legal/disclaimers "Disclaimers")
---
# Cookies Policy | Ondo Finance
[Legal](https://docs.ondo.finance/legal)
Cookies Policy
Cookies Policy
==============
> _Last Updated: January 2023_
Introduction and Scope of Policy[](https://docs.ondo.finance/legal/cookies-policy#introduction-and-scope-of-policy)
--------------------------------------------------------------------------------------------------------------------
This Ondo Finance Inc. Cookies Policy (“Policy”) applies to your interaction with Ondo Finance or any of its subsidiaries or affiliates (“Ondo” or “we”).
About "Cookies"[](https://docs.ondo.finance/legal/cookies-policy#about-cookies)
--------------------------------------------------------------------------------
Cookies are pieces of data stored on your device. Browser cookies are assigned by a web server to the browser on your device. When you return to a site you have visited before, your browser gives this data back to the server. Mobile applications may also use cookies.
We do not generally use cookies. We do not intentionally collect information to customize your experience on the website or the Ondo user interface (UI) to the Ondo Protocol. (“Sites” or “Site”).
Industry standards are currently evolving, and we may not separately respond to or take any action with respect to a “do not track” configuration set in your internet browser. Other parties that may collect information about your web browsing behavior when you use our Site are generally limited to service providers who may only use any information collected to provide services for us and not to provide services or advertising for any other party. Note, however, that we also provide certain widgets or tools on our sites that allow you to interact with third parties who provide these features, such as tools that allow web surfers to easily share information on another platform. At other times, information from a third party may be embedded on our Site, such as a map. These widgets, tools, and informational items often function through the use of third-party cookies utilized by the third party site. As a result, these third parties may have access to information about your web browsing on the pages of our Site where these widgets, tools, or information are placed. You may wish to review information at third party sites, where you have an account, to determine how these third parties treat data that they obtain through the use of cookies.
Do you have to accept Cookies?[](https://docs.ondo.finance/legal/cookies-policy#do-you-have-to-accept-cookies)
---------------------------------------------------------------------------------------------------------------
You may be able to set your browser to reject cookies. If you set your browser options to disallow cookies, you may limit the functionality we can provide when you visit our Site. The latest versions of internet browsers provide cookie management tools, such as the ability to delete or reject cookies. We recommend that you refer to information supplied by browser providers for more specific information, including how to use these tools.
Additional Technologies[](https://docs.ondo.finance/legal/cookies-policy#additional-technologies)
--------------------------------------------------------------------------------------------------
We do not typically use additional technologies such as pixel tags, web beacons, and clear GIFs. We may permit third-party service providers to use these technologies. They may use these technologies for purposes such as determining viewing and response rates.
Using Information[](https://docs.ondo.finance/legal/cookies-policy#using-information)
--------------------------------------------------------------------------------------
In addition to the uses described above, we may use information for purposes as allowed by law such as: servicing; communicating with you; improving our Site, products, or services; legal compliance; risk control; information security; anti-fraud purposes; tracking website usage, such as number of hits, pages visited, and the length of user sessions in order to evaluate the usefulness of our sites.
Sharing[](https://docs.ondo.finance/legal/cookies-policy#sharing)
------------------------------------------------------------------
We may share information with service providers with whom we work, such as service providers and companies that help us service you better. When permitted or required by law, we may share information with additional third parties for purposes including response to legal process. As applicable, please see our Privacy Policy for more information on how we may share information with affiliates and third parties.
[Privacy Policy](https://docs.ondo.finance/legal/privacy-policy "Privacy Policy")
[Disclaimers](https://docs.ondo.finance/legal/disclaimers "Disclaimers")
---
# Privacy Policy | Ondo Finance
[Legal](https://docs.ondo.finance/legal)
Privacy Policy
Privacy Policy
==============
> _Last Updated: February 4, 2025_
This Privacy Policy ("**Policy**") describes how Ondo Finance Inc. and its directly or indirectly controlled affiliates, including but not limited to, Ondo I LP and Ondo USDY LLC, ("**Ondo**," "**we**," "**us**" or "**our**") may collect, use and disclose information, and your choices regarding this information. Please read this Policy carefully and contact us with questions at [legal@ondo.finance](mailto:legal@ondo.finance)
.
Applicability of This Policy[](https://docs.ondo.finance/legal/privacy-policy#applicability-of-this-policy)
------------------------------------------------------------------------------------------------------------
This Policy applies to our Services, which include our websites and mobile applications featuring this Policy (collectively, the "**Sites**"), the services and tools we provide on or make available via our platform, any interaction with Ondo’s APIs or other user interfaces relating to issuances of our tokenized assets, bridging or conversion tools made available for your use, insights, or subscribing in or managing blockchain-based smart contracts or any other features or content we own or operate or third party applications or smart contracts relying on such Ondo interfaces or smart contracts, and related services, including but not limited to blockchain-based tokens that are generated or transferred by or otherwise interact with any such smart contracts (collectively, the "**Services and Tools**"). If you do not agree with the terms of this Policy, do not access or use the Services and Tools, Sites, or otherwise interact with our business.
This Policy does not address our privacy practices relating to Ondo job applicants, employees and other personnel. This Policy is also not a contract and does not create any legal rights or obligations. We may also choose or be required by law to provide different or additional disclosures relating to the processing of your information, which should not be interpreted as limiting the terms of this Policy.
What We Collect[](https://docs.ondo.finance/legal/privacy-policy#what-we-collect)
----------------------------------------------------------------------------------
The categories of information we collect depend on how you interact with us and our Services and Tools. Ondo collects information that individuals provide directly to us, information we collect automatically when individuals interact with us, and information we collect from third-party sources and other organizations.
### Information You Provide[](https://docs.ondo.finance/legal/privacy-policy#information-you-provide)
We may collect the following information you provide directly to us in connection with our Services and Tools:
* **Contact Information**, such as your name, email address, physical address, and communication preferences.
* **Financial Information**, such as your blockchain addresses, blockchain wallet information, asset holdings, transaction history, and associated fees paid.
* **Transaction Information** such as information about the transactions you make on or using our Services and Tools, such as the type of transaction, transaction amount, and timestamp.
* **Background Information** for KYC and other regulatory customer diligence requirements, which may include collection of your passport, photos, bank account statements, assets, utility bills, proof of income, incorporation documents, and tax ID and verification information.
* **Interaction Information**, such as the information you submit through your interactions with us, including feedback, communications, inquiries, questionnaires and other survey responses, your use of the Services and Tools, and information you provide to our first- and third-party support teams, including via our help chat.
### Information We Collect Automatically[](https://docs.ondo.finance/legal/privacy-policy#information-we-collect-automatically)
As is true of many digital platforms, we and our third-party providers may also collect certain information from an individual’s device, browsing actions, and site usage patterns automatically when visiting or interacting with our Services and Tools, which may include:
* **Online Identifiers**, such as geo location/tracking details, browser fingerprint, mobile carrier, MAC address, user settings, mobile ad identifiers, Internet service provider, operating system, browser name and version, personal IP addresses, the URL entered and the referring page/campaign, date/time of visit, the time spent on our services, and any errors that may occur during the visit to our services.
* **Usage Data**, such as the electronic path taken to our services, through our services, and when exiting our services, as well as information pertaining to usage and activity on our services (including pages visited, links clicked, content interacted with, and duration and frequency of the activities).
* **Location Information**, such as IP-derived location, used at the city level for fraud detection, customer support and product improvement purposes.
* **Cookies and Other Tracking Technologies**. We, and third parties we authorize, collect information through (i) cookies or small data files that are stored on an individual’s device or browser and (ii) other, similar technologies, such as web beacons, pixels, embedded scripts, location-identifying technologies and logging technologies (collectively, “**Cookies**”). We use Cookies to automatically collect and use or disclose information for the purposes described in this Privacy Policy, including to analyze and track data, determine the popularity of certain content, and better understand each user’s online activity. We may combine this Cookie information with other information we collect about you. You may choose to set your web browser to refuse Cookies, or to alert you when Cookies are being sent. If you do so, please note that some parts of our Services and Tools may not function properly.
### Infrmation from Third Parties and Other Sources[](https://docs.ondo.finance/legal/privacy-policy#infrmation-from-third-parties-and-other-sources)
We also obtain personal information from third-party sources, which we often combine with personal information we collect either automatically or directly from an individual.
We may receive the same categories of personal information as described above from the following third parties:
* **Affiliates**. We may receive information from other companies owned or controlled by Ondo, and other companies owning or under common ownership with Ondo, particularly when we collaborate in providing the Services and Tools.
* **Social Media**. If an individual chooses to interact with us on social media, we may collect personal information about them from their social media account that they make public. We use personal information collected in connection with their social media account to communicate with them, better understand their interests and preferences, and better understand our user base in the aggregate.
* **Identity Verification Providers**. In certain circumstances, we may engage third-party identity verification providers to help us verify the identity of a specific individual with whom we are interacting. This information is used primarily for purposes of preventing fraud.
* **Data Analytics Providers**. We rely on third-party providers to help us collect analytics relating to our services and user base. These data analytics providers often collect personal information directly from individuals or public blockchains and share some or all of this information with us in connection with their analytics services.
* **Other Service Providers**. Other service providers that perform services solely on our behalf, such as website hosting and marketing providers, collect personal information and often share some or all of this information with us in connection with their services.
* **Information Providers**. We may from time to time obtain information from third-party information providers to correct or supplement personal information we collect. For example, we may obtain background check information from credit bureaus or updated contact information from third-party information providers to connect with an individual who may be interested in our services.
* **Publicly Available Sources**. We collect personal information about individuals that we do not otherwise have, such as information publicly available on various blockchains (see below), public contact information or an individual’s interest in our services from publicly available sources. We may combine this information with the information we collect from an individual directly.
### Our Collection of Blockchain Information[](https://docs.ondo.finance/legal/privacy-policy#our-collection-of-blockchain-information)
Blockchain is a shared, immutable ledger used to record transactions of assets. In connection with our services, we may collect the following current and historical blockchain information directly from individuals, from the third parties identified above, or from public blockchains themselves:
* **Account Address**: The unique blockchain address or domain from or to which assets are transferred.
* **Wallet Information**: The wallet provider and wallet connected to a specific account address.
* **Account Balance & Assets**: The balance associated with the blockchain address, as well as the assets stored in connection with that account.
* **Transaction Details**: The transaction identifier, blockchain position for the transaction, date and time of the transaction, type of transaction, amount sent or received, fee amount, account address of the sender and recipient, and storage size of the transaction.
We may in certain circumstances combine the blockchain information we obtain with the information described above, such as where you are required to connect a blockchain wallet (such as through Coinbase Wallet, WalletConnect, Fortmatic, Ledger, or Trust Wallet) to the Service to facilitate the account address creation and wallet linking.
How We Use Information[](https://docs.ondo.finance/legal/privacy-policy#how-we-use-information)
------------------------------------------------------------------------------------------------
We use your information and blockchain information in accordance with your instructions, including any applicable terms in the Terms of Use, to provide data processing as described in the policies and agreements of our affiliates, and as required by applicable law. We may also use the information we collect for:
### Providing Services and Tools and Features[](https://docs.ondo.finance/legal/privacy-policy#providing-services-and-tools-and-features)
We may use the information we collect to provide, personalize, maintain, and improve our products and Services and Tools, including as we described in the Terms of Use. This includes using information to:
* operate, maintain, customize, test, measure, and improve our Services and Tools, and manage our organization and business;
* facilitate and process transactions;
* send information, including confirmations, notices, updates, technical alerts, security alerts, surveys, and support and administrative messages;
* communicate with you about the Services and Tools and events offered by Ondo and others and provide news and information that we think will interest you;
* personalize and improve your experience on our Services and Tools;
* monitor and analyze trends, usage, and activities in connection with our Services and Tools; and
* to create de-identified or aggregated data.
### Safety and Security[](https://docs.ondo.finance/legal/privacy-policy#safety-and-security)
We may use your information to help maintain the safety, security, and integrity of you and our Services and Tools, including to:
* protect, investigate, and deter against fraudulent, unauthorized, or illegal activity;
* monitor and verify identity or service access, combat spam, malware or security risks;
* perform internal operations necessary to provide our Services and Tools, including to test, diagnose, and troubleshoot software bugs and technical and operational problems;
* help maintain the safety, security, and integrity of our property and Services and Tools, technology assets, and business;
* enforce our agreements with third parties, and address violations of our Terms of Use or agreements for other Services and Tools;
* detect, prevent, investigate, or provide notice of security incidents or other malicious, deceptive, fraudulent, or illegal activity and protect the rights and property of Ondo and others; and
* comply with applicable security laws and regulations.
### User Support[](https://docs.ondo.finance/legal/privacy-policy#user-support)
We may use information we collect to provide support, including to:
* direct questions to the appropriate support person;
* respond to your comments and questions and provide customer service
* investigate, troubleshoot, address and resolve user concerns and problems using the Services and Tools; and
* monitor and improve our customer support responses and processes.
### Research and Development[](https://docs.ondo.finance/legal/privacy-policy#research-and-development)
We may use the information we collect for testing, research, analysis, and product development to improve your experience. This helps us to improve and enhance the safety and security of our Services and Tools, improve our ability to prevent the use of our Services and Tools for illegal or improper purposes and develop new features and products relating to our Services and Tools.
### Legal and Regulatory Compliance[](https://docs.ondo.finance/legal/privacy-policy#legal-and-regulatory-compliance)
We may verify your identity and conduct KYC and other customer diligence requirements by comparing the personal information you provide against third-party databases and public records, or conducting a background check. We may use the information we collect to investigate or address claims or disputes relating to use of our Services and Tools, or as otherwise allowed by applicable law, or as requested by regulators, government entities, and official inquiries. We may process the information to facilitate business transactions and reorganizations impacting the structure of our business, or to otherwise comply with our legal and financial obligations.
### Direct Marketing[](https://docs.ondo.finance/legal/privacy-policy#direct-marketing)
We may use the information we collect to market our Services and Tools to you. This may include sending you communications about our Services and Tools, features, promotions, surveys, news, updates, and events, and managing your participation in these promotions and events. If you do not want us to send you marketing communications, please opt out by selecting "unsubscribe" to any marketing email sent by us or by contacting us at [legal@ondo.finance](mailto:legal@ondo.finance)
.
How We Share & Disclose Information[](https://docs.ondo.finance/legal/privacy-policy#how-we-share--disclose-information)
-------------------------------------------------------------------------------------------------------------------------
We may share your information and blockchain information in the following circumstances:
* **With Affiliates**: We share information with other companies owned or controlled by Ondo, and other companies owning or under common ownership or control with Ondo, particularly when we collaborate in providing Services and Tools.
* **At Your Direction**. We may share information with third parties you engage with through our Services and Tools or as needed to fulfill a request or transaction. For example, you may let us share personal information with others for their own marketing uses. Those uses will be subject to the recipient’s privacy policies.
* **To Comply with Our Legal Obligations**. We may share your information: (A) to cooperate with government or regulatory investigations; (B) when we are compelled to do so by a subpoena, court order, or similar legal procedure; (C) when we believe in good faith that the disclosure of personal information is necessary to prevent harm to another person; (D) to report suspected illegal activity; or (E) to investigate violations of our User Agreement or any other applicable policies.
* **With Service Providers**. We may share your information with service providers who help facilitate business and compliance operations such as marketing and technology services. Our contracts require these service providers to only use your information in connection with the services they perform for us.
* **Identity Verification Providers**. Where we engage a third-party identity verification provider to help us verify the identity of a specific individual with whom we are interacting, we will typically provide the third-party identity verification provider sufficient information to facilitate the identity verification service.
* **With Public Blockchains**. We will make information relating to certain transactions available on public blockchains to the extent such information is customarily shared in connection with consummating a blockchain transaction. Please note this information is publicly available and may be shared freely.
* **During a Change to Our Business**. If we engage in a merger, acquisition, bankruptcy, dissolution, reorganization, sale of some or all of our assets or stock, financing, public offering of securities, acquisition of all or a portion of our business, a similar transaction or proceeding, or steps in contemplation of such activities, some or all of your information may be shared or transferred, subject to standard confidentiality arrangements.
* **Legal Obligations and Rights**. We share or otherwise disclose information to third parties, such as our lawyers, other professional advisors and law enforcement:
* Where necessary to obtain advice or otherwise protect and manage our business interests;
* In connection with the establishment, exercise, or defense of legal claims;
* To comply with laws or to respond to lawful requests or legal process, including lawful requests by public authorities to meet national security or law enforcement requirements;
* To protect our rights and property and the rights and property of others, including to enforce our agreements and policies;
* To detect, suppress, or prevent fraud;
* To protect the health and safety of us and others; or
* As otherwise required by applicable law.
* **Aggregated or De-identified Data**. We may share aggregated and/or anonymized data with others for their own uses.
Legal Bases for Using Your Information[](https://docs.ondo.finance/legal/privacy-policy#legal-bases-for-using-your-information)
--------------------------------------------------------------------------------------------------------------------------------
Where the law requires the identification of the legal basis on which rely to process your information, the legal bases for using your information as set out in this Privacy Policy are as follows:
* Where we need to perform the contract we are about to enter into or have entered into with you for the Services and Tools.
* Where it is necessary for our legitimate interests (or those of a third party) and your interests and fundamental rights do not override those interests.
* Where we need to comply with a legal or regulatory obligation in the relevant jurisdiction.
* Where we have your consent to process your information in a certain way.
Your Rights and Choices[](https://docs.ondo.finance/legal/privacy-policy#your-rights-and-choices)
--------------------------------------------------------------------------------------------------
If you would like further information in relation to your legal rights under applicable law or would like to exercise any of them, please contact us using the information in the “Contact Us” section below at any time. Your local laws may permit you to request that we:
* provide access to and/or a copy of certain information we hold about you.
* update information which is out of date or incorrect.
* delete certain information that we are holding about you.
* restrict the way that we process and disclose certain of your information.
* permit you to revoke your consent for the processing of your information.
We will consider all requests and provide our response within the time period stated by applicable law and as otherwise required by applicable law. Please note, however, that certain information may be exempt from such requests in some circumstances, which may include if we need to keep processing your information for our legitimate interests or to comply with a legal obligation. We may request you provide us with information necessary to confirm your identity before responding to your request.
Data Retention[](https://docs.ondo.finance/legal/privacy-policy#data-retention)
--------------------------------------------------------------------------------
To view or update your information, contact us at [legal@ondo.finance](mailto:legal@ondo.finance)
. We store your information throughout the life of your use of any Sites or Services and Tools and retain your information for a minimum of five (5) years to comply with our legal obligations or to resolve disputes. If you cease using any Sites or Services and Tools, we may still process and share your information with third parties, such as may be necessary to prevent fraud and assist law enforcement, as required by law, or as otherwise to protection our legal rights, or those of others, such as in the case of litigation, or otherwise in accordance with this Policy.
Security[](https://docs.ondo.finance/legal/privacy-policy#security)
--------------------------------------------------------------------
We maintain administrative, technical and physical safeguards designed to protect the personal information we maintain against unauthorized access or disclosure. No system can be completely secure. Therefore, although we take steps to secure your information, we cannot guarantee that your information, searches, or other communication will always remain secure. You are responsible for all activity relating to any of your blockchain network addresses and/or blockchain-based wallets.
Age Limitations[](https://docs.ondo.finance/legal/privacy-policy#age-limitations)
----------------------------------------------------------------------------------
To the extent prohibited by applicable law, we do not allow use of our Services and Tools or Sites by anyone younger than the legal age in the jurisdiction in which the user resides. If you learn that anyone younger than the legal age has unlawfully provided us with personal data, please contact us at [legal@ondo.finance](mailto:legal@ondo.finance)
and we will take steps to delete such information, close any such accounts, and, to the extent possible, prevent the user from continuing to use our Services and Tools.
Changes to This Policy[](https://docs.ondo.finance/legal/privacy-policy#changes-to-this-policy)
------------------------------------------------------------------------------------------------
If we make any changes, we will change the Last Updated date above. We encourage you to review this Policy to stay informed. If we make material changes, we will provide additional notice, such as via the email specified in your account or through the Services and Tools or Sites.
Online Tracking Opt-out Guide[](https://docs.ondo.finance/legal/privacy-policy#online-tracking-opt-out-guide)
--------------------------------------------------------------------------------------------------------------
Like many companies online, we use services provided by Google and other companies that use Cookies. These services rely on Cookies to collect directly from your device information about your browsing activities, your interactions with websites, and the device you are using to connect to the Internet. There are a number of ways to opt out of having your online activity and device data collected through these services, which we have summarized below:
* **Blocking cookies in your browser**. Most browsers let you remove or reject cookies, including cookies used for interest-based advertising. To do this, follow the instructions in your browser settings. Many browsers accept cookies by default until you change your settings. For more information about cookies, including how to see what cookies have been set on your device and how to manage and delete them, visit [www.allaboutcookies.org (opens in a new tab)](http://www.allaboutcookies.org/)
.
* **Blocking advertising ID use in your mobile settings**. Your mobile device settings may provide functionality to limit use of the advertising ID associated with your mobile device for interest-based advertising purposes. Using privacy plug-ins or browsers. You can block our websites from setting cookies used for interest-based ads by using a browser with privacy features.
* **Platform opt-outs**. The following advertising partner offers opt-out features that let you opt-out of use of your information for interest-based advertising:
* **Google Analytics**. For more information about how Google uses your data, please visit [Google Analytics Privacy Policy (opens in a new tab)](https://policies.google.com/privacy?hl=en-US)
. You can also view Google’s currently available opt-out options for Google Analytics [here (opens in a new tab)](https://tools.google.com/dlpage/gaoptout)
.
* **Advertising industry opt-out tools**. You can also use the opt-out options set forth below to limit use of your information for interest-based advertising by participating companies. Note that because these opt-out mechanisms are specific to the device or browser on which they are exercised, you will need to opt out on every browser and device that you use.
* Digital Advertising Alliance: [http://optout.aboutads.info (opens in a new tab)](http://optout.aboutads.info/)
Network
* Advertising Initiative: [http://optout.networkadvertising.org/ (opens in a new tab)](http://optout.networkadvertising.org/)
### Additional Disclosure for Our Consumers and Customers[](https://docs.ondo.finance/legal/privacy-policy#additional-disclosure-for-our-consumers-and-customers)
This Additional Disclosure governs our collection, use and sharing of personal information that users provide to us to initiate or complete the process of interacting with the financial Services and Tools. To the extent there are conflicting provisions between this Additional Disclosure and other sections of the Privacy Policy, the Additional Disclosure will govern.
The types of personal information we collect and share can include:
* Contact details
* Transaction history
* Cryptocurrency balances and wallets
When you are no longer our customer, we continue to share your information as described in this Policy.
Reasons We Can Share Your Personal Information[](https://docs.ondo.finance/legal/privacy-policy#reasons-we-can-share-your-personal-information)
------------------------------------------------------------------------------------------------------------------------------------------------
We need to share users' personal information to operate certain aspects of our Sites, Services and Tools and business. The below includes information on whether we share your personal information, the reasons we share your personal information and whether you can limit this sharing.
* We share users' personal information for our everyday business purposes, including to operate, maintain and upgrade our Services and Tools and to support the use thereof, and to respond to court orders and legal investigations. You cannot limit our sharing of this information.
* We share users’ personal information for our marketing purposes, such as to offer our products and services to you. You cannot limit our sharing of this information.
* We do not share users’ personal information for joint marketing with partner financial companies.
* We do not share users' personal information for nonaffiliates to market to you, subject to the terms of this Policy and any agreement between you and us.
"Affiliates" refer to companies related by common ownership or control; "nonaffiliates" refer to companies no related by common ownership or control; and "joint marketing" refers to a formal agreement between nonaffiliated financial companies that together market financial products or services to you.
### How Does Ondo Protect My Personal Information?[](https://docs.ondo.finance/legal/privacy-policy#how-does-ondo-protect-my-personal-information)
To protect your personal information from unauthorized access and use, we use security measures that comply with applicable law. These measures include computer safeguards and secured files and buildings.
### How Does Ondo Collect My Personal Information?[](https://docs.ondo.finance/legal/privacy-policy#how-does-ondo-collect-my-personal-information)
We collect your personal information when you register for an account through the Services and Tools before you deposit Digital Assets in the Services and Tools, make transactions using the Services and Tools, withdraw Digital Assets from the Services and Tools, or otherwise interact with us or the Services and Tools. We may also collect your personal information automatically through your use of the Services and Tools or from other companies.
Contact Us[](https://docs.ondo.finance/legal/privacy-policy#contact-us)
------------------------------------------------------------------------
Please contact us if you have any questions about this Policy or if you are seeking to exercise any of your statutory rights. Subject to applicable laws, we will respond within a reasonable timeframe. You may contact us at [legal@ondo.finance](mailto:legal@ondo.finance)
.
[Terms of Service](https://docs.ondo.finance/legal/terms-of-service "Terms of Service")
[Cookies Policy](https://docs.ondo.finance/legal/cookies-policy "Cookies Policy")
---
# Terms of Service | Ondo Finance
[Legal](https://docs.ondo.finance/legal)
Terms of Service
Terms of Service
================
> _Last Updated: February 4, 2025_
These terms of service, together with any documents and additional terms they expressly incorporate by reference, which includes any applicable Tool Specific Terms (as defined below) and any other terms and conditions or other agreement that Ondo Finance Inc. ("**Ondo**," "**we**," "**us**" and "**our**") posts publicly or makes available to you or the company or other legal entity you represent ("**you**" or "**your**") (collectively, these "**Terms**"), are entered into between Ondo and you concerning your use of, and access to, Ondo's websites, including ondo.finance, and Ondo’s web applications, mobile applications, and all associated sites linked thereto by Ondo or its affiliates (collectively with any materials and services available therein, and successor website(s) or application(s) thereto, the "**Site**") and the Services (as defined in Section 2.1).
**THESE TERMS ARE SEPARATED INTO TWO PARTS: (A) PART I OF THESE TERMS SETS OUT THE GENERAL TERMS THAT APPLY TO THE SITE AND THE SERVICES (“GENERAL TERMS”); AND (B) PART II OF THESE TERMS SETS OUT THE TOOL SPECIFIC TERMS (AS DEFINED IN THE PARAGRAPH DIRECTLY BELOW).** Unless otherwise specified, all references to Sections in these Terms are references to Sections in the General Terms.
**NOTICE REGARDING TOOLS**: As part of the Services (as defined in Section 2.1), Ondo may provide you the ability to access certain self-service tools that are deployed on blockchain networks (each, a **“Tool”**). For example, Ondo may enable you to access Tools through messaging protocols to interact with centralized or decentralized applications; APIs; and other software that Ondo has developed or otherwise makes available to you. Each Tool may be subject to additional terms that are specific to that Tool, including the Tool Specific Terms that are described in Part II of these Terms (the **“Tool Specific Terms”**). **Ondo provides access to Tools for convenience only. You are solely responsible for your use of, and interactions with, any Tool, and you are solely responsible for reviewing and complying with any and all applicable eligibility requirements. If you use or otherwise interact with a Tool, you do so at your own risk. You expressly relieve Ondo from any and all liability arising from any noncompliance with applicable eligibility requirements or your use of any Tools. Entering into bilateral transactions (including smart contract based decentralized transactions) involving the Tools and/or cryptocurrency or other blockchain based assets (collectively, “Digital Assets”) is not part of the Services and any such activities or transactions are done at your own risk. You acknowledge and agree that Ondo does not provide execution, settlement, or clearing services of any kind and is not responsible for the execution, settlement, or clearing of transactions automated through a blockchain. You acknowledge that any execution, settlement or clearing of decentralized blockchain transactions (including involving a Digital Asset) occurs directly on the Ethereum blockchain (or such other blockchain as may be indicated in the relevant Services interface) and that Ondo is not involved in or responsible for any such activity or transactions.**
By clicking "I agree" (or similar language) to these Terms, acknowledging these Terms by other means, or otherwise accessing or using the Site or the Services, you accept and agree to be bound by and to comply with these Terms, including, without limitation, the mandatory arbitration provision in Section 14, and acknowledge that you have read and understood our [Privacy Policy (opens in a new tab)](https://docs.ondo.finance/legal/privacy-policy)
as further described in Section 15.1. If you do not agree to these Terms, then you must not access or use the Site or the Services. Please carefully review the disclosures and disclaimers set forth in Section 12 and elsewhere in these Terms in their entirety before accessing or using any software, services, or other offerings developed, owned or otherwise made available by Ondo. These Terms set forth important details about the legal obligations associated with your use of the Services.
PLEASE READ THESE TERMS CAREFULLY TO ENSURE THAT YOU UNDERSTAND EACH PROVISION. THESE TERMS CONTAIN A MANDATORY INDIVIDUAL ARBITRATION PROVISION AND CLASS ACTION/JURY TRIAL WAIVER IN SECTION 14 THAT REQUIRE, UNLESS YOU OPT OUT PURSUANT TO THE INSTRUCTIONS IN SECTION 14, THE EXCLUSIVE USE OF FINAL AND BINDING ARBITRATION ON AN INDIVIDUAL BASIS TO RESOLVE DISPUTES BETWEEN YOU AND US, INCLUDING WITHOUT LIMITATION ANY CLAIMS THAT AROSE OR WERE ASSERTED BEFORE YOU AGREED TO THESE TERMS. TO THE FULLEST EXTENT PERMITTED BY LAW, YOU EXPRESSLY WAIVE YOUR RIGHT TO SEEK RELIEF IN A COURT OF LAW AND TO HAVE A JURY TRIAL ON YOUR CLAIMS, AS WELL AS YOUR RIGHT TO PARTICIPATE AS A PLAINTIFF OR CLASS MEMBER IN ANY CLASS, COLLECTIVE, PRIVATE ATTORNEY GENERAL OR REPRESENTATIVE ACTION OR PROCEEDING.
**_PART I: General Terms_**[](https://docs.ondo.finance/legal/terms-of-service#part-i-general-terms)
-----------------------------------------------------------------------------------------------------
### 1\. **Modifications to These Terms**[](https://docs.ondo.finance/legal/terms-of-service#1-modifications-to-these-terms)
We reserve the right, in our sole discretion, to modify these Terms from time to time. If we make changes, we will provide you with notice of such changes, such as by providing notice through the Services or updating the "Last Updated" date at the top of these Terms. Unless we state otherwise in our notice, all such modifications are effective immediately, and your continued use of the Site and the Services after we provide that notice will confirm your acceptance of the changes. If you do not agree to the amended Terms, then you must stop using the Site and the Services.
### 2\. **Use of Services**[](https://docs.ondo.finance/legal/terms-of-service#2-use-of-services)
2.1 The Services. The Site provides information regarding and, subject to eligibility requirements and the successful completion of Ondo's onboarding process and the ability to access certain services operated by Ondo, as well as certain Tools (collectively, “Services”).
2.2 Conditions. As a condition to accessing or using the Services or the Site, you represent and warrant to Ondo the following:
2.2.1 if you are entering into these Terms as an individual, then you are of legal age in the jurisdiction in which you reside and you have the legal capacity to enter into these Terms and be bound by them and if you are entering into these Terms as an entity, then you must have the legal authority to accept these Terms on that entity's behalf, in which case "you" (except as used in this paragraph) will mean that entity;
2.2.2 you are not a resident, national, or agent of Iran, Cuba, North Korea, Syria, or the Crimean Region of the Ukraine or any other country to which the United States embargoes goods or imposes similar sanctions (collectively, "**Restricted Territories**");
2.2.3 you are not a member of any sanctions list or equivalent maintained by the United States government, the United Kingdom government, the European Union, or the United Nations (collectively, "**Sanctions Lists Persons**") and you do not intend to transact with any Restricted Person or Sanctions List Person;
2.2.4 you do not, and will not, use VPN software or any other privacy or anonymization tools or techniques to circumvent, or attempt to circumvent, any restrictions that apply to the Services; and
2.2.5 your access to the Services is not (a) prohibited by and does not otherwise violate or assist you to violate any domestic or foreign law, rule, statute, regulation, by-law, order, protocol, code, decree, or another directive, requirement, or guideline, published or in force that applies to or is otherwise intended to govern or regulate any person, property, transaction, activity, event or other matter, including any rule, order, judgment, directive or other requirement or guideline issued by any domestic or foreign federal, provincial or state, municipal, local or other governmental, regulatory, judicial or administrative authority having jurisdiction over Ondo, you, the Site or the Services, or as otherwise duly enacted, enforceable by law, the common law or equity (collectively, "**Applicable Laws**"); or (b) contribute to or facilitate any illegal activity.
2.3 As a condition to accessing or using the Services or the Site, you acknowledge, understand, and agree to the following:
2.3.1 from time to time the Site and the Services may be inaccessible or inoperable for any reason, including, without limitation: (a) equipment malfunctions; (b) periodic maintenance procedures or repairs that Ondo or any of its suppliers or contractors may undertake from time to time; (c) causes beyond Ondo's control or that Ondo could not reasonably foresee; (d) disruptions and temporary or permanent unavailability of underlying blockchain infrastructure; or (e) unavailability of third-party service providers or external partners for any reason;
2.3.2 we reserve the right to disable or modify access to the Site and the Services at any time in the event of any breach of these Terms, including, without limitation, if we reasonably believe any of your representations and warranties may be untrue or inaccurate, and we will not be liable to you for any losses or damages you may suffer as a result of or in connection with the Site or the Services being inaccessible to you at any time or for any reason;
2.3.3 the Site and the Services may evolve, which means Ondo may apply changes, replace, or discontinue (temporarily or permanently) the Services at any time in its sole discretion;
2.3.4 the general pricing information provided on the Site is informational and does not represent an offer, a solicitation of an offer, or any advice regarding, or recommendation to enter into, a transaction with Ondo;
2.3.5 Ondo does not act as an agent for you or any other user of the Site or the Services;
2.3.6 you are solely responsible for your use of the Services, including all of your transfers of Digital Assets and the custody and control of your Digital Assets;
2.3.7 to the fullest extent not prohibited by Applicable Law, we owe no fiduciary duties or liabilities to you or any other party, and that to the extent any such duties or liabilities may exist at law or in equity, you hereby irrevocably disclaim, waive, and eliminate those duties and liabilities;
2.3.8 you are solely responsible for reporting and paying any taxes applicable to your use of the Services; and
2.3.9 we have no control over, or liability for, the delivery, quality, safety, legality, or any other aspect of any Digital Assets that you may transfer to or from a third party, and we are not responsible for ensuring that an entity with whom you transact completes the transaction or is authorized to do so, and if you experience a problem with any transactions in Digital Assets using the Services, then you bear the entire risk.
2.4 As a condition to accessing or using the Services or the Site, you covenant to Ondo the following:
2.4.1 in connection with using the Services, you only will transfer legally-obtained Digital Assets that belong to you;
2.4.2 you will comply with all Applicable Laws in connection with using the Services, and you will not use the Site or the Services if the laws of your country, or any other Applicable Law, prohibit you from doing so;
2.4.3 any Digital Assets you use in connection with the Services are either owned by you or you are validly authorized to carry our actions using such Digital Assets;
2.4.4 in addition to complying with all restrictions, prohibitions, and other provisions of these Terms, you will, at all times, (a) ensure that all information that you provide on the Site and during your use of the Services is current, complete, and accurate; and (b) maintain the security and confidentiality of your private keys associated with your public Ether address, passwords, API keys, private keys associated with your Services account and other related credentials.
### 3\. **Fees and Price Estimates**[](https://docs.ondo.finance/legal/terms-of-service#3-fees-and-price-estimates)
In connection with your use of the Services, you are required to pay all fees necessary for interacting with the Ethereum or any other applicable blockchain, including transaction costs, as well as any other fees reflected on the Site at the time of your use of the Services. Where relevant, although we attempt to provide accurate fee information, this information reflects our estimates of fees, which may vary from the actual fees paid to use the Services and interact with the Ethereum or any other applicable blockchain.
### 4\. **No Professional Advice or Fiduciary Duties**[](https://docs.ondo.finance/legal/terms-of-service#4-no-professional-advice-or-fiduciary-duties)
Unless otherwise stated, all information provided in connection with your access and use of the Site and the Services is for informational purposes only and should not be construed as professional advice. You should not take, or refrain from taking, any action based on any information contained on the Site or any other information that we make available at any time, including, without limitation, blog posts, articles, links to third-party content, discord content, news feeds, tutorials, tweets, and videos. Before you make any financial, legal, or other decisions involving the Services, you should seek independent professional advice from an individual who is licensed and qualified in the area for which such advice would be appropriate. The Terms are not intended to, and do not, create or impose any fiduciary duties on us. You further agree that the only duties and obligations that we owe you are those set out expressly in these Terms.
### 5\. **Prohibited Activity**[](https://docs.ondo.finance/legal/terms-of-service#5-prohibited-activity)
You may not use the Services to engage in the categories of activity set forth below ("**Prohibited Uses**"). The specific activities set forth below are representative, but not exhaustive, of Prohibited Uses. If you are uncertain as to whether or not your use of the Services involves a Prohibited Use or have other questions about how these requirements apply to you, then please contact us at [legal@ondo.finance](mailto:legal@ondo.finance)
. By using the Site or Services, you confirm that you will not use the Site or Services to do any of the following:
5.1 violate any Applicable Laws including, without limitation, any relevant and applicable anti-money laundering and anti-terrorist financing laws and sanctions programs, such as, without limitation, the US Department of Treasury's Office of Foreign Asset Controls;
5.2 engage in transactions involving items that infringe or violate any copyright, trademark, right of publicity or privacy or any other proprietary right under Applicable Law, including but not limited to, sales, distribution, or access to counterfeit music, movies, software, or other licensed materials without the appropriate authorization from the rights holder; use of Ondo's intellectual property, name, or logo, including use of Ondo's trade or service marks, without express consent from Ondo or in a manner that otherwise harm Ondo; any action that implies an untrue endorsement by or affiliation with Ondo;
5.3 use the Services in any manner that could interfere with, disrupt, negatively affect, or inhibit other users from fully enjoying the Services, or that could damage, disable, overburden, or impair the functioning of the Site or the Services in any manner;
5.4 engage in activity that violates any applicable law, rule, or regulation concerning the integrity of trading markets, including (but not limited to) the manipulative tactics commonly known as spoofing and wash trading.
5.5 circumvent any content-filtering techniques, security measures or access controls that Ondo employs on the Site, including, without limitation, through the use of a VPN;
5.6 use any robot, spider, crawler, scraper, or other automated means or interface not provided by us, to access the Services or to extract data, or introduce any malware, virus, Trojan horse, worm, logic bomb, drop-dead device, backdoor, shutdown mechanism or other harmful material into the Site or the Services;
5.7 provide false, inaccurate, or misleading information while using the Site or the Services or engage in activity that operates to defraud Ondo, other users of the Services, or any other person;
5.8 use or access the Site or Services to transmit or exchange Digital Assets that are the direct or indirect proceeds of any criminal or fraudulent activity, including, without limitation, terrorism or tax evasion;
5.9 use the Site in any way that is, in our sole discretion, libelous, defamatory, profane, obscene, pornographic, sexually explicit, indecent, lewd, vulgar, suggestive, harassing, stalking, hateful, threatening, offensive, discriminatory, bigoted, abusive, inflammatory, fraudulent, deceptive, or otherwise objectionable or likely or intended to incite, threaten, facilitate, promote, or encourage hate, racial intolerance, or violent acts against others; 5.10 use the Site or the Services from a jurisdiction that we have, in our sole discretion, determined is a jurisdiction where the use of the Site or the Services is prohibited;
5.10 harass, abuse, or harm of another person or entity, including Ondo's employees and service providers; impersonate another user of the Services or otherwise misrepresent yourself;
5.11 engage in activity that violates any applicable law, rule, or regulation of the United States or another relevant jurisdiction, including (but not limited to) the restrictions and regulatory requirements imposed by US law; or
5.12 encourage, induce or assist any third party, or yourself attempt, to engage in any of the activities prohibited under this Section 5 or any other provision of these Terms.
### 6\. **Content**[](https://docs.ondo.finance/legal/terms-of-service#6-content)
You hereby grant to us a royalty-free, fully paid-up, sublicensable, transferable, perpetual, irrevocable, non- exclusive, worldwide license to use, copy, modify, create derivative works of, display, perform, publish and distribute, in any form, medium, or manner, any content that is available to other users as a result of your use of the Site or the Services (collectively, "**Your Content**"), including, without limitation, for promoting Ondo, its affiliates, the Services or the Site. You represent and warrant that (a) you own Your Content or have the right to grant the rights and licenses in these Terms; and (b) Your Content and our use of Your Content, as licensed herein, does not and will not violate, misappropriate or infringe on any third party's rights.
### 7\. **Proprietary Rights**[](https://docs.ondo.finance/legal/terms-of-service#7-proprietary-rights)
7.1 Any Ondo names, logos, and other marks used on the Site or as a part of the Services are trademarks owned by Ondo, its affiliates, or its applicable licensors. You may not copy, imitate, or use them without the prior written consent of Ondo or the applicable licensors, and these Terms do not grant you any rights in those trademarks. You may not remove, obscure, or alter any legal notices displayed in or along with the Services.
### 8\. **Third-Party Services**[](https://docs.ondo.finance/legal/terms-of-service#8-third-party-services)
The Services may enable you to access or view links to other World Wide Web or accessible sites, applications, or resources, and may enable you to access, download or otherwise interact with content, services, applications and/or resources provided by third parties (for example, eligible crypto wallet providers and blockchain networks) that are not owned or controlled by Ondo (collectively, “**Third-Party Services**”), and certain functionality of the Service may require you to register for or otherwise use Third-Party Services. You acknowledge and agree that Ondo is not responsible for the availability of such Third-Party Services, and that Ondo does not endorse and is not responsible or liable for any content, advertising, products, or other materials on or available from such Third-Party Services. You further acknowledge and agree that Ondo shall not be responsible or liable, directly or indirectly, for any damage or loss caused or alleged to be caused by or in connection with use of or reliance on any Third-Party Services, including without limitation your use of or reliance on any content, goods, or services available on or through any Third-Party Services.
YOUR ACCESS TO AND/OR USE OF ANY THIRD-PARTY SERVICE, INCLUDING BUT NOT LIMITED TO ANY INTERACTION OR TRANSACTION BY YOU WITH, ON OR THROUGH ANY THIRD-PARTY SERVICE, IS SUBJECT TO THE APPLICABLE THIRD-PARTY SERVICE’S TERMS AND CONDITIONS AND/OR ANY OTHER TERMS MADE AVAILABLE ON OR AGREED TO BY YOU IN CONNECTION WITH SUCH THIRD-PARTY SERVICE, AND ANY TRANSACTION AND/OR INTERACTION BY YOU WITH, ON OR THROUGH A THIRD-PARTY SERVICE IS SOLELY BETWEEN YOU AND THE APPLICABLE THIRD PARTY. IF YOU ACCESS OR USE A THIRD-PARTY SERVICE, YOU DO SO AT YOUR OWN RISK, AND YOU UNDERSTAND THAT THESE TERMS DO NOT APPLY TO YOUR USE OF SUCH THIRD-PARTY SERVICE. YOU EXPRESSLY RELIEVE US FROM ANY AND ALL LIABILITY ARISING FROM YOUR USE OF OR RELIANCE ON ANY THIRD-PARTY SERVICE.
### 9\. **Modification, Suspension, and Termination**[](https://docs.ondo.finance/legal/terms-of-service#9-modification-suspension-and-termination)
We may, at our sole discretion, from time to time and with or without prior notice to you, modify, suspend or disable (temporarily or permanently) the Services, in whole or in part, for any reason whatsoever, including, without limitation, to only allow open Ondo Finance funds to be closed. Upon termination of your access, your right to use the Services will immediately cease. We will not be liable for any losses suffered by you resulting from any modification to any Services or from any modification, suspension, or termination, for any reason, of your access to all or any portion of the Site or the Services. The following sections of these Terms will survive any termination of your access to the Site or the Services, regardless of the reasons for its expiration or termination, in addition to any other provision which by law or by its nature should survive: Sections 7 through 15.
### 10\. **Assumption of Risks**[](https://docs.ondo.finance/legal/terms-of-service#10-assumption-of-risks)
10.1 By utilizing the Services or interacting with the Site in any way, you represent and warrant that you understand the inherent risks associated with cryptographic systems and blockchain-based networks; Digital Assets, including the usage and intricacies of native Digital Assets, like Ether (ETH); Ethereum blockchain-based tokens, and systems that interact with blockchain-based networks. Ondo does not own or control any of the underlying software through which blockchain networks are formed. In general, the software underlying blockchain networks, including the Ethereum blockchain, is open source, such that anyone can use, copy, modify, and distribute it. By using the Services, you acknowledge and agree (a) that Ondo is not responsible for the operation of the software and networks underlying the Services, (b) that there exists no guarantee of the functionality, security, or availability of that software and networks, and (c) that the underlying networks are subject to sudden changes in operating rules, such as those commonly referred to as "forks," which may materially affect the Services. Blockchain networks use public/private key cryptography. You alone are responsible for securing your private key(s). We do not have access to your private key(s). Losing control of your private key(s) will permanently and irreversibly deny you access to Digital Assets on the Ethereum blockchain or other blockchain-based network. Neither Ondo nor any other person or entity will be able to retrieve or protect your Digital Assets. If your private key(s) are lost, then you will not be able to transfer your Digital Assets to any other blockchain address or wallet. If this occurs, then you will not be able to realize any value or utility from the Digital Assets that you may hold.
10.2 The Services and your Digital Assets could be impacted by one or more regulatory inquiries or regulatory actions, which could impede or limit the ability of Ondo to continue to make available its proprietary software and, thus, could impede or limit your ability to access or use the Services.
10.3 You acknowledge and understand that cryptography is a progressing field with advances in code cracking or other technical advancements, such as the development of quantum computers, which may present risks to Digital Assets and the Services, and could result in the theft or loss of your Digital Assets. To the extent possible, we intend to update Ondo-developed or owned software related to the Services to incorporate additional security measures necessary to address risks presented from technological advancements, but that intention does not guarantee or otherwise ensure full security of the Services.
10.4 You understand that the Ethereum blockchain and other blockchain-based networks remain under development, which creates technological and security risks when using the Services in addition to uncertainty relating to Digital Assets and transactions therein. You acknowledge that the cost of transacting on the Ethereum blockchain and other blockchain-based networks may be variable and may increase at any time causing impact to any activities taking place on the Ethereum blockchain or other blockchain-based network, which may result in price fluctuations or increased costs when using the Services.
10.5 You acknowledge that the Services are subject to flaws and that you are solely responsible for evaluating any code provided by the Services or Site. This warning and others Ondo provides in these Terms in no way evidence or represent an on-going duty to alert you to all of the potential risks of utilizing the Services or accessing the Site.
10.6 Although we intend to provide accurate and timely information on the Site and during your use of the Services, the Site and other information available when using the Services may not always be entirely accurate, complete, or current and may also include technical inaccuracies or typographical errors. To continue to provide you with as complete and accurate information as possible, information may be changed or updated from time to time without notice, including, without limitation, information regarding our policies. Accordingly, you should verify all information before relying on it, and all decisions based on information contained on the Site or as part of the Services are your sole responsibility. No representation is made as to the accuracy, completeness, or appropriateness for any particular purpose of any pricing information distributed via the Site or otherwise when using the Services. Prices and pricing information may be higher or lower than prices available on platforms providing similar services.
10.7 Any use or interaction with the Services requires a comprehensive understanding of applied cryptography and computer science to appreciate the inherent risks, including those listed above. You represent and warrant that you possess relevant knowledge and skills. Any reference to a type of Digital Asset on the Site or otherwise during the use of the Services does not indicate our approval or disapproval of the technology on which the Digital Asset relies, and should not be used as a substitute for your understanding of the risks specific to each type of Digital Asset.
10.8 Use of the Services, in particular for Digital Assets transactions and entering into Ondo Finance funds, may carry financial risk. Digital Assets and decentralized protocols are highly experimental, risky, and volatile. Transactions entered into in connection with the Services are irreversible, final and there are no refunds. You acknowledge and agree that you will access and use the Site and the Services at your own risk. The risk of loss in transacting in Digital Assets using Ondo Finance funds can be substantial. You should, therefore, carefully consider whether such transactions are suitable for you in light of your circumstances and financial resources. By using the Services, you represent and warrant that you have been, are, and will be solely responsible for making your independent appraisal and investigations into the risks of a given Ondo Finance pool transaction. You represent that you have sufficient knowledge, market sophistication, professional advice, and experience to make your evaluation of the merits and risks of any transaction conducted in connection with the Services. You accept all consequences of using the Services, including the risk that you may lose access to your Digital Assets indefinitely. All transaction decisions are made solely by you. Notwithstanding anything in these Terms, we accept no responsibility whatsoever for, and will in no circumstances be liable to you in connection with, your use of the Services.
10.9 We must comply with Applicable Law, which may require us to, upon request by government agencies, take certain actions or provide information, which may not be in your best interests and which may occur without notice to you.
10.10 You understand that the Service remains under development, which creates technological, transaction related, and other risks when using the Services. These risks include, among others, delays in trades, withdrawals, and deposits resulting from the servers of Ondo or any other operator of the Services being offline; an incorrect display of information on the Site in the case of server errors; or transactions using the Services being rolled back in the case of server errors. You acknowledge that these risks may have a material impact on your transactions using the Services, which may result in, among other things, failing to fulfill transactions at your desired price or at all.
10.11 You hereby assume, and agree that Ondo will have no responsibility or liability for, the risks set forth in this Section 10. You hereby irrevocably waive, release and discharge all claims, whether known or unknown to you, against Ondo, its affiliates, and their respective shareholders, members, directors, officers, employees, agents, and representatives, suppliers, and contractors related to any of the risks set forth in this Section 10.
### 11\. **Indemnification**[](https://docs.ondo.finance/legal/terms-of-service#11-indemnification)
You will defend, indemnify, and hold harmless Ondo, its affiliates, and its and its affiliates' respective stockholders, members, directors, officers, managers, employees, attorneys, agents, representatives, suppliers, and contractors (collectively, "**Indemnified Parties**") from any claim, demand, lawsuit, action, proceeding, investigation, liability, damage, loss, cost or expense, including without limitation reasonable attorneys' fees, arising out of or relating to (a) your use of, or conduct in connection with, the Site or the Services (including, without limitation, the Service); (b) Digital Assets associated with your Ethereum or other applicable blockchain address; (c) any feedback or user content you provide to Ondo, if any, concerning the Site or the Services; (d) your violation of these Terms; or (e) your infringement or misappropriation of the rights of any other person or entity. If you are obligated to indemnify any Indemnified Party, Ondo (or, at its discretion, the applicable Indemnified Party) will have the right, in its sole discretion, to control any action or proceeding and to determine whether Ondo wishes to settle, and if so, on what terms, and you agree to corporate with Ondo in the defense.
### 12\. **Disclosures; Disclaimers**[](https://docs.ondo.finance/legal/terms-of-service#12-disclosures-disclaimers)
ONDO IS A DEVELOPER AND OWNER OF SOFTWARE. ONDO DOES NOT OPERATE A DIGITAL ASSET OR DERIVATIVES EXCHANGE PLATFORM OR OFFER TRADE EXECUTION OR CLEARING SERVICES AND, THEREFORE, HAS NO OVERSIGHT, INVOLVEMENT, OR CONTROL CONCERNING YOUR TRANSACTIONS USING THE SERVICES AND/OR TOOLS. ANY SECONDARY TRANSACTIONS BETWEEN USERS OF THE SERVICES ARE EXECUTED PEER-TO-PEER DIRECTLY BETWEEN THE USERS' ETHEREUM OR OTHER APPLICABLE BLOCKCHAIN ADDRESSES THROUGH A SMART CONTRACT. YOU ARE RESPONSIBLE FOR COMPLYING WITH ALL APPLICABLE LAWS THAT GOVERN YOUR USE OF THE SERVICES AND/OR TOOLS, INCLUDING, BUT NOT LIMITED TO, THE COMMODITY EXCHANGE ACT AND THE REGULATIONS PROMULGATED THEREUNDER BY THE US COMMODITY FUTURES TRADING COMMISSION ("**CFTC**"), THE FEDERAL SECURITIES LAWS AND THE REGULATIONS PROMULGATED THEREUNDER BY THE US SECURITIES AND EXCHANGE COMMISSION ("**SEC**") AND ALL FOREIGN APPLICABLE LAWS. YOU UNDERSTAND THAT ONDO IS NOT REGISTERED OR LICENSED BY THE BVI FINANCIAL SERVICES COMMISSION, THE CFTC, SEC, OR ANY FINANCIAL REGULATORY AUTHORITY. ONDO DOES NOT OWN OR CONTROL THE UNDERLYING SOFTWARE PROTOCOLS THAT ARE USED IN CONNECTION WITH ETHEREUM OR OTHER APPLICABLE BLOCKCHAINS. IN GENERAL, DECENTRALIZED PROTOCOLS ARE OPEN SOURCE AND ANYONE CAN USE, COPY, MODIFY, AND DISTRIBUTE THEM. ONDO IS NOT RESPONSIBLE FOR THE OPERATION OF DECENTRALIZED PROTOCOLS, AND ONDO MAKES NO GUARANTEE OF THEIR FUNCTIONALITY, SECURITY, OR AVAILABILITY.
TO THE MAXIMUM EXTENT PERMITTED UNDER APPLICABLE LAW, THE SITE AND THE SERVICES (AND ANY OF THEIR CONTENT OR FUNCTIONALITY) PROVIDED BY OR ON BEHALF OF US ARE PROVIDED ON AN "AS IS" AND "AS AVAILABLE" BASIS, AND WE EXPRESSLY DISCLAIM, AND YOU HEREBY WAIVE, ANY REPRESENTATIONS, CONDITIONS OR WARRANTIES OF ANY KIND, WHETHER EXPRESS OR IMPLIED, LEGAL, STATUTORY OR OTHERWISE, OR ARISING FROM STATUTE, OTHERWISE IN LAW, COURSE OF DEALING, OR USAGE OF TRADE, INCLUDING, WITHOUT LIMITATION, THE IMPLIED OR LEGAL WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, QUALITY OR FITNESS FOR A PARTICULAR PURPOSE, TITLE, SECURITY, AVAILABILITY, RELIABILITY, ACCURACY, QUIET ENJOYMENT AND NON-INFRINGEMENT OF THIRD PARTY RIGHTS. WITHOUT LIMITING THE FOREGOING, WE DO NOT REPRESENT OR WARRANT THAT THE SITE OR THE SERVICES (INCLUDING ANY DATA RELATING THERETO) WILL BE UNINTERRUPTED, AVAILABLE AT ANY PARTICULAR TIME, OR ERROR-FREE. FURTHER, WE DO NOT WARRANT THAT ERRORS IN THE SITE OR THE SERVICES ARE CORRECTABLE OR WILL BE CORRECTABLE.
YOU ACKNOWLEDGE THAT YOUR DATA ON THE SITE MAY BECOME IRRETRIEVABLY LOST OR CORRUPTED OR TEMPORARILY UNAVAILABLE DUE TO A VARIETY OF CAUSES, AND AGREE THAT, TO THE MAXIMUM EXTENT PERMITTED UNDER APPLICABLE LAW, WE WILL NOT BE LIABLE FOR ANY LOSS OR DAMAGE CAUSED BY DENIAL-OF-SERVICE ATTACKS, SOFTWARE FAILURES, VIRUSES OR OTHER TECHNOLOGICALLY HARMFUL MATERIALS (INCLUDING THOSE WHICH MAY INFECT YOUR COMPUTER EQUIPMENT), PROTOCOL CHANGES BY THIRD-PARTY PROVIDERS, INTERNET OUTAGES, FORCE MAJEURE EVENTS OR OTHER DISASTERS, SCHEDULED OR UNSCHEDULED MAINTENANCE, OR OTHER CAUSES EITHER WITHIN OR OUTSIDE OUR CONTROL.
THE DISCLAIMER OF IMPLIED WARRANTIES CONTAINED HEREIN MAY NOT APPLY IF AND TO THE EXTENT SUCH WARRANTIES CANNOT BE EXCLUDED OR LIMITED UNDER THE APPLICABLE LAW OF THE JURISDICTION IN WHICH YOU RESIDE.
### 13\. **Limitation of Liability**[](https://docs.ondo.finance/legal/terms-of-service#13-limitation-of-liability)
IN NO EVENT SHALL ONDO'S AGGREGATE LIABILITY (TOGETHER WITH ITS AFFILIATES, INCLUDING ITS AND ITS AFFILIATES' RESPECTIVE STOCKHOLDERS, MEMBERS, DIRECTORS, MANAGERS, OFFICERS, EMPLOYEES, ATTORNEYS, AGENTS, REPRESENTATIVES, SUPPLIERS, OR CONTRACTORS) ARISING OUT OF OR IN CONNECTION WITH THE SITE AND THE SERVICES (AND ANY OF THEIR CONTENT AND FUNCTIONALITY), ANY PERFORMANCE OR NONPERFORMANCE OF THE SERVICES, YOUR DIGITAL ASSETS, OR ANY TOOL, SERVICE OR OTHER ITEM MADE AVAILABLE BY OR ON BEHALF OF ONDO, WHETHER UNDER CONTRACT, TORT, NEGLIGENCE, CIVIL LIABILITY, STATUTE, STRICT LIABILITY OR OTHER THEORY OF LIABILITY EXCEED THE LESSER OF US $50 OR THE AMOUNT OF FEES PAID BY YOU TO ONDO UNDER THESE TERMS, IF ANY, IN THE TWELVE (12) MONTH PERIOD IMMEDIATELY PRECEDING THE EVENT GIVING RISE TO THE CLAIM FOR LIABILITY, EXCEPT TO THE EXTENT OF A FINAL JUDICIAL DETERMINATION THAT SUCH DAMAGES WERE THE RESULT OF ONDO'S GROSS NEGLIGENCE, FRAUD, WILLFUL MISCONDUCT OR INTENTIONAL VIOLATION OF THE LAW.
### 14\. **Dispute Resolution & Arbitration**[](https://docs.ondo.finance/legal/terms-of-service#14-dispute-resolution--arbitration)
14.1 PLEASE READ THE FOLLOWING SECTION CAREFULLY BECAUSE IT REQUIRES YOU TO ARBITRATE CERTAIN DISPUTES AND CLAIMS WITH ONDO AND LIMITS HOW YOU CAN SEEK RELIEF FROM ONDO. This Section 14 (this “**Arbitration Provision**”) applies to and governs any dispute, controversy, or claim between you and us that arises out of or relates to, directly or indirectly: (a) these Terms, including the formation, existence, breach, termination, enforcement, interpretation, validity, and enforceability thereof; (b) access to or use of the Site or the Services; (c) any transactions through, by, or using the Site or the Services; or (d) any other aspect of your relationship or transactions with us, directly or indirectly, as a visitor to or user of the Site or the Services (each, a “**Claim**,” and, collectively, “**Claims**”). This Arbitration Provision applies, without limitation, to all Claims that arose or were asserted before or after your consent to these Terms. You and Ondo agree that any dispute arising out of or related to these Terms, the Site or the Services is personal to you and Ondo and that any dispute will be resolved solely through individual action, and will not be brought as a class arbitration, class action, or any other type of representative proceeding. Except as otherwise set forth in these Terms, the FAA (as defined in Section 15.7) governs the interpretation and enforcement of this Arbitration Provision.
14.2 **Right to Opt Out.** You have the right to opt out of this Arbitration Provision by sending written notice of your decision to opt out to [legal@ondo.finance](mailto:legal@ondo.finance)
within 30 days after you first accept these Terms. Your notice must include your full legal name and address and an unequivocal statement of your intention to opt out of this Arbitration Provision. Opting out of this Arbitration Provision does not affect (a) the binding nature of any other part of these Terms, including the provisions regarding controlling law or the courts in which any disputes must be brought; or (b) any other arbitration agreements that you may currently have, or may enter in the future, with us.
14.3 **Dispute Resolution Process.** For any Claim, you agree that you will first contact us at [legal@ondo.finance](mailto:legal@ondo.finance)
and attempt to resolve the Claim with us informally. In the unlikely event that we have not been able to resolve a Claim after sixty (60) days, we each agree to resolve such Claim exclusively through binding arbitration by JAMS before a single arbitrator (the “**Arbitrator**”), under the JAMS International Arbitration Rules (the “**Rules**”), except as provided herein. JAMS may be contacted at [www.jamsadr.com (opens in a new tab)](https://www.jamsadr.com/)
, where the Rules are available. In the event of any conflict between the Rules and this Arbitration Provision, this Arbitration Provision will control. The seat of the arbitration shall be New York City, New York, and the language of the arbitration shall be English. Judgment upon the award rendered by the arbitrator(s) may be entered in any court having jurisdiction thereof. Each party will bear their own attorneys’ fees and costs in any action subject to this Arbitration Provision; and the rule that the prevailing or substantially prevailing party be reimbursed attorneys’ fees and costs will not apply with respect to the arbitration or otherwise. Each party irrevocably and unconditionally waives any objection that it may now or hereafter have to the laying of venue of any action or proceeding arising out of or relating to these Terms in the courts referred to in this Section 14.2.
14.4 **Class Action / Jury Trial Waiver.** WITH RESPECT TO ALL PERSONS AND ENTITIES, REGARDLESS OF WHETHER THEY HAVE OBTAINED OR USED THE SITE FOR PERSONAL, COMMERCIAL OR OTHER PURPOSES, ALL DISPUTES, CONTROVERSIES OR CLAIMS MUST BE BROUGHT IN THE PARTIES' INDIVIDUAL CAPACITY, AND NOT AS A PLAINTIFF OR CLASS MEMBER IN ANY PURPORTED CLASS ACTION, COLLECTIVE ACTION OR OTHER REPRESENTATIVE PROCEEDING. THIS WAIVER APPLIES TO CLASS ARBITRATION, AND UNLESS WE AGREE OTHERWISE, THE ARBITRATOR MAY NOT CONSOLIDATE MORE THAN ONE PERSON'S CLAIMS. YOU AGREE THAT, BY ENTERING INTO THE AGREEMENT, YOU AND ONDO ARE EACH WAIVING THE RIGHT TO A TRIAL BY JURY OR TO PARTICIPATE IN A CLASS ACTION, COLLECTIVE ACTION, OR OTHER REPRESENTATIVE PROCEEDING OF ANY KIND.
14.5 **Equitable Relief.** NOTHING IN THIS ARBITRATION PROVISION WILL BE DEEMED AS: PREVENTING US FROM SEEKING INJUNCTIVE OR OTHER EQUITABLE RELIEF FROM THE COURTS AS NECESSARY TO PREVENT THE ACTUAL OR THREATENED INFRINGEMENT, MISAPPROPRIATION, OR VIOLATION OF OUR DATA SECURITY, CONFIDENTIAL INFORMATION, OR INTELLECTUAL PROPERTY RIGHTS; OR PREVENTING YOU FROM ASSERTING CLAIMS IN A SMALL CLAIMS COURT, PROVIDED THAT YOUR CLAIMS QUALIFY AND SO LONG AS THE MATTER REMAINS IN SUCH COURT AND ADVANCES ON ONLY AN INDIVIDUAL (NON-CLASS, NON-COLLECTIVE, AND NON-REPRESENTATIVE) BASIS.
14.6 **Severability.** If any portion of this Section 14 is found to be unenforceable or unlawful for any reason, (a) the unenforceable or unlawful provision shall be severed from these Terms; (b) severance of the unenforceable or unlawful provision shall have no impact whatsoever on the remainder of this Section 14 or the parties' ability to compel arbitration of any remaining claims on an individual basis under this Section 14; and (c) to the extent that any claims must therefore proceed on a class, collective, consolidated, or representative basis, such claims must be litigated in a civil court of competent jurisdiction and not in arbitration, and the parties agree that litigation of those claims shall be stayed pending the outcome of any individual claims in arbitration. Further, if any part of this Section 14 is found to prohibit an individual claim seeking public injunctive relief, then that provision will have no effect to the extent such relief is allowed to be sought out of arbitration, and the remainder of this Section 14 will be enforceable.
### 15\. **General Information**[](https://docs.ondo.finance/legal/terms-of-service#15-general-information)
15.1 **Privacy Policy.** Please refer to our [Privacy Policy (opens in a new tab)](https://docs.ondo.finance/legal/privacy-policy)
for information about how we collect, use, share and otherwise process information about you.
15.2 **Consent to Electronic Delivery.** You consent to receive all communications, agreements, documents, receipts, notices, and disclosures electronically (collectively, our "**Communications**") that we provide in connection with these Terms or any Services. You agree that we may provide our Communications to you by posting them on the Site or by emailing them to you at the email address you provide in connection with using the Services, if any. You should maintain copies of our Communications by printing a paper copy or saving an electronic copy. You may also contact us with questions, complaints, or claims concerning the Services at [legal@ondo.finance](mailto:legal@ondo.finance)
.
15.3 **Remedies.** Any right or remedy of Ondo set forth in these Terms is in addition to, and not in lieu of, any other right or remedy whether described in these Terms, under Applicable Law, at law, or in equity. The failure or delay of Ondo in exercising any right, power, or privilege under these Terms shall not operate as a waiver thereof.
15.4 **Severability.** The invalidity or unenforceability of any of these Terms shall not affect the validity or enforceability of any other of these Terms, all of which shall remain in full force and effect.
15.5 **Force Majeure.** We will have no responsibility or liability for any failure or delay in performance of the Site or any of the Services, or any loss or damage that you may incur, due to any circumstance or event beyond our control, including without limitation any flood, extraordinary weather conditions, earthquake, or other act of God, fire, war, insurrection, riot, labor dispute, accident, action of government, communications, power failure, or equipment or software malfunction.
15.6 **Assignment.** You may not assign or transfer any right to use the Site or the Services, or any of your rights or obligations under these Terms, without our express prior written consent, including by operation of law or in connection with any change of control. We may assign or transfer any or all of our rights or obligations under these Terms, in whole or in part, without notice or obtaining your consent or approval.
15.7 **Governing Law.** The interpretation and enforcement of these Terms, and any dispute related to these Terms, the Site or the Services, will be governed by and construed and enforced under the laws of the state of Connecticut, without regard to its conflicts of laws rules. Notwithstanding the preceding sentence, the Federal Arbitration Act (9 U.S.C. §§ 1-16) (“**FAA**”) governs the interpretation and enforcement of the Arbitration Provision and preempts all state laws (and laws of other jurisdictions) to the fullest extent permitted by Applicable Laws. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. You agree that we may initiate a proceeding related to the enforcement or validity of our intellectual property rights or other proprietary rights, including any provisional relief required to prevent irreparable harm, in any court having jurisdiction. For any other proceeding that is not subject to arbitration under these Terms, the courts located in the state of Connecticut will have exclusive jurisdiction. You waive any objection to venue in any such courts. You further agree that the state of Connecticut is the proper and exclusive forum for any appeals of an arbitration award or for trial court proceedings in the event that the Arbitration Provision is found to be unenforceable.
15.8 **Headings.** Headings of sections are for convenience only and shall not be used to limit or construe such sections.
15.9 **Entire Agreement.** These Terms contain the entire agreement between you and Ondo, and supersede all prior and contemporaneous understandings between you and Ondo regarding the Site and the Services. For clarity, these Terms shall apply regardless of any separate agreements that you may have entered into in connection with an acquisition of tokens made available by Ondo (including, without limitation, OUSG and USDY), and any such other agreements shall remain in full force and effect. 15.10 Interpretation. In the event of any conflict between these Terms and any other agreement you may have with us, these Terms will control unless the other agreement specifically identifies these Terms and declares that the other agreement supersedes these Terms. 15.11 No Third Parties. You agree that, except as otherwise expressly provided in these Terms, there shall be no third-party beneficiaries to the Terms other than the Indemnified Parties.
**_PART II: Tool Specific Terms_**[](https://docs.ondo.finance/legal/terms-of-service#part-ii-tool-specific-terms)
-------------------------------------------------------------------------------------------------------------------
TThe Tool Specific Terms below are additional terms that apply to your access to and use of the specific Tools identified below. The Tool Specific Terms are incorporated by reference into and form a part of the Terms. Any capitalized terms not defined in the Tool Specific Terms have the meanings set forth above. In the event of any conflict between a provision in the General Terms and any applicable Tool Specific Terms, the provision in the applicable Tool Specific Terms will govern.
### **Bridge Tool Terms**[](https://docs.ondo.finance/legal/terms-of-service#bridge-tool-terms)
The bridge tool (“**Bridge Tool**”) enables eligible users to interact with one or more public blockchains that underlie an asset-based token (“**Token**”) in order to bridge such Token from one blockchain to another blockchain.
#### 1\. **Eligibility; Token Requirements**[](https://docs.ondo.finance/legal/terms-of-service#1-eligibility-token-requirements)
1.1 You may only access and utilize the Bridge Tool if you are eligible to hold a Token in accordance with and subject to (a) the Terms, including these Bridge Tool Specific Terms; and (b) the terms, conditions, and other eligibility and requirements established by the relevant issuer of such Token (“**Token Requirements**”).
1.2 YOU ARE SOLELY RESPONSIBLE FOR COMPLIANCE WITH THE TOKEN REQUIREMENTS, AND THE PROVISION OF THE BRIDGE TOOL IS NOT A VERIFICATION OR CONFIRMATION BY ONDO OF YOUR COMPLIANCE THEREWITH. WITHOUT LIMITING THE GENERALITY OF SECTION 12 (DISCLOSURES; DISCLAIMERS), YOU EXPRESSLY RELIEVE ONDO FROM ANY AND ALL LIABILITY ARISING FROM ANY NONCOMPLIANCE WITH THE TOKEN REQUIREMENTS OR YOUR USE OF THE BRIDGE TOOL. ONDO IS NOT AND WILL NOT BE RESPONSIBLE OR LIABLE TO YOU FOR ANY LOSSES YOU INCUR AS THE RESULT OF ANY NONCOMPLIANCE WITH THE TOKEN REQUIREMENTS OR YOUR USE OF THE BRIDGE TOOL, INCLUDING BUT NOT LIMITED TO ANY LOSSES, DAMAGES OR CLAIMS ARISING FROM: (I) ANY ISSUES WITH A TOKEN ISSUER OR A BLOCKCHAIN NETWORK; (II) USER ERROR, SUCH AS FORGOTTEN PASSWORDS OR INCORRECTLY CONSTRUED SMART CONTRACTS OR OTHER TRANSACTIONS; (III) SERVER FAILURE OR DATA LOSS; (IV) CORRUPTED FILES; OR (V) UNAUTHORIZED ACCESS OR ACTIVITIES BY THIRD PARTIES, INCLUDING, BUT NOT LIMITED TO, THE USE OF VIRUSES, PHISHING, BRUTE-FORCING OR OTHER MEANS OF ATTACK AGAINST THE BRIDGE TOOL.
#### 2\. **Wallet Connection and Other Third-Party Services**[](https://docs.ondo.finance/legal/terms-of-service#2-wallet-connection-and-other-third-party-services)
2.1 To use the Bridge Tool, you may be required to connect an eligible crypto wallet and provide certain information through functionality offered by a Third-Party Service, which may involve registering for, and accessing, downloading or otherwise installing additional software.
2.2 If you connect an eligible crypto wallet or otherwise connect to the Bridge Tool with a Third-Party Service, you give us and third parties (for example, validator addresses and other service providers that support the functionality of the Bridge Tool) permission to access and use your information from that Third-Party Service as permitted by that Third-Party Service, and if necessary, to store and use your credentials for that Third-Party Service.
#### 3\. **Bridge Tool Fees**[](https://docs.ondo.finance/legal/terms-of-service#3-bridge-tool-fees)
You may be required to pay certain fees (for example, gas fees) in order to instruct the execution of smart contracts in connection with the Bridge Tool and to otherwise use the Bridge Tool.
### **Converter Tool Terms**[](https://docs.ondo.finance/legal/terms-of-service#converter-tool-terms)
Ondo's "Converter" tool (“**Convert Tool**”) enables eligible users to convert non-rebasing tokens (“**Non-Rebasing Tokens**”) in order to acquire rebasing versions of such tokens (“**Rebasing Tokens**”) by facilitating the calling of associated third-party smart contract functions through an interface on the ondo.finance website, and vice-versa.
#### 1\. **Eligibility**[](https://docs.ondo.finance/legal/terms-of-service#1-eligibility)
1.1 You may only access and utilize the Convert Tool if you are eligible in accordance with and subject to the Terms, including these Convert Tool Terms.
1.2 THE CONVERT TOOL IS NOT AVAILABLE TO ALL USERS AND MAY NOT BE AVAILABLE TO YOU. THE CONVERT TOOL IS NOT AVAILABLE TO CUSTOMERS THAT DO NOT MEET THE ELIGIBILITY REQUIREMENTS FOR THE APPLICABLE REBASING TOKEN OR NON-REBASING TOKEN (“**ELIGIBILITY REQUIREMENTS**”) AS MAY BE SET FORTH IN THE ONDO DOCUMENTATION FOR SUCH TOKEN OR OTHERWISE COMMUNICATED OR MADE AVAILABLE BY ONDO OR THE THIRD PARTY OFFERING AND/OR ISSUING SUCH TOKEN. FOR EXAMPLE, THE CONVERT TOOL IS NOT AVAILABLE TO CUSTOMERS THAT ARE LOCATED AND/OR ORGANIZED IN, OR RESIDENTS AND/OR CITIZENS OF, JURISDICTIONS WHERE ACQUIRING OR REDEEMING OR OTHERWISE TRANSACTING WITH THE APPLICABLE TOKEN IS PROHIBITED OR OTHERWISE RESTRICTED BY ONDO OR BY APPLICABLE LAW, AND NOTWITHSTANDING ANYTHING TO THE CONTRARY IN THE TERMS, ALL SUCH CUSTOMERS SHALL BE DEEMED “RESTRICTED PERSONS” (AS DEFINED IN THE TERMS).
1.3 YOU ARE SOLELY RESPONSIBLE FOR REVIEWING AND COMPLYING WITH THE APPLICABLE ELIGIBILITY REQUIREMENTS. YOU EXPRESSLY RELIEVE ONDO FROM ANY AND ALL LIABILITY ARISING FROM ANY NONCOMPLIANCE WITH THE ELIGIBILITY REQUIREMENTS OR YOUR USE OF THE CONVERT TOOL. ONDO IS NOT AND WILL NOT BE RESPONSIBLE OR LIABLE TO YOU FOR ANY LOSSES YOU INCUR AS THE RESULT OF ANY NONCOMPLIANCE WITH THE ELIGIBILITY REQUIREMENTS OR YOUR USE OF THE CONVERT TOOL, INCLUDING BUT NOT LIMITED TO ANY LOSSES, DAMAGES OR CLAIMS ARISING FROM: (I) ANY ISSUES WITH ANY TOKEN ISSUER OR BLOCKCHAIN NETWORK; (II) USER ERROR, SUCH AS FORGOTTEN PASSWORDS OR INCORRECTLY CONSTRUED SMART CONTRACTS OR OTHER TRANSACTIONS; (III) SERVER FAILURE OR DATA LOSS; (IV) CORRUPTED FILES; OR (V) UNAUTHORIZED ACCESS OR ACTIVITIES BY THIRD PARTIES, INCLUDING, BUT NOT LIMITED TO, THE USE OF VIRUSES, PHISHING, BRUTE-FORCING OR OTHER MEANS OF ATTACK AGAINST THE CONVERT TOOL.
#### 2\. **Wallet Connection and Other Third-Party Services**[](https://docs.ondo.finance/legal/terms-of-service#2-wallet-connection-and-other-third-party-services-1)
2.1 To use the Convert Tool, you may be required to connect an eligible crypto wallet and provide certain information through functionality offered by a Third-Party Service, which may involve registering for, and accessing, downloading or otherwise installing additional software.
2.2 If you connect an eligible crypto wallet or otherwise connect to the Convert Tool with a Third-Party Service, you give us and third parties (for example, validator addresses and other service providers that support the functionality of the Convert Tool) permission to access and use your information from that Third-Party Service as permitted by that Third-Party Service, and if necessary, to store and use your credentials for that Third-Party Service.
#### 3\. **Convert Tool Fees**[](https://docs.ondo.finance/legal/terms-of-service#3-convert-tool-fees)
You may be required to pay certain fees (for example, gas fees) in order to instruct the execution of smart contracts in connection with the Convert Tool and to otherwise use the Convert Tool.
[Legal](https://docs.ondo.finance/legal "Legal")
[Privacy Policy](https://docs.ondo.finance/legal/privacy-policy "Privacy Policy")
---
# Disclaimers | Ondo Finance
[Legal](https://docs.ondo.finance/legal)
Disclaimers
Disclaimers
===========
The tokenized assets referenced herein (Global Markets tokens including Ondo tokenized stocks and Ondo tokenized ETFs, USDY tokens and OUSG tokens) (the "Tokens") have not been registered under the US Securities Act of 1933, as amended ("Act") or the securities or financial instrument laws of any other jurisdiction. The Tokens may not be offered or sold in the United States or to US persons unless registered under the Act or an exemption from the registration requirements thereof is available. The Tokens are offered and sold in the European Economic Area and the United Kingdom solely to qualified investors, and in Switzerland solely to professional clients. Other jurisdiction-based prohibitions and restrictions apply ([Global Markets](https://docs.ondo.finance/legal/ondo-global-markets/eligibility)
; [USDY](https://docs.ondo.finance/legal/general-access-products/usdy/faq/eligibility)
). The issuer of Tokens is not registered as an investment company under the US Investment Company Act of 1940, as amended, or as an Alternative Investment Fund or Undertaking for Collective Investment in Transferable Securities in the European Economic Area, or under the securities or financial instrument laws of any other jurisdiction.
Global Markets tokens provide their holders with economic exposure to the value of their underlying publicly traded assets, including the value of dividends (less applicable tax withholdings). However, the Tokens are not themselves stocks or ETFs, and they do not provide their holders with rights to hold or receive their respective underlying assets. Ondo does not endorse, Ondo does not make any representation or warranty whatsoever (express or implied, including but not limited to any warranty of merchantability, fitness for a particular purpose or non-infringement) regarding, and ONDO SHALL NOT HAVE ANY LIABILITY WHATSOEVER WITH RESPECT TO ANYONE'S USE OF, any third-party products, services or technologies deployed to or accessible via Ondo Chain. Nothing herein constitutes any offer to sell, or any solicitation of an offer to buy, any assets (including any Tokens or assets that may be deployed to or accessible via Ondo Chain). Acquiring any such assets will involve risks. A holder of any such assets may incur losses, including total loss of their purchase price. Past performance may not be (and for the Tokens will not be) an indication of future results. Additional terms and conditions apply. See [docs.ondo.finance/legal/terms-of-service](https://docs.ondo.finance/legal/terms-of-service)
, [docs.ondo.finance (opens in a new tab)](https://docs.ondo.finance/)
and [ondo.finance/ousg (opens in a new tab)](https://ondo.finance/ousg)
for details.
[Cookies Policy](https://docs.ondo.finance/legal/cookies-policy "Cookies Policy")
[Ondo Summit 2026 Terms](https://docs.ondo.finance/legal/ondo-summit-2026-terms "Ondo Summit 2026 Terms")
---
# Unknown
Ondo RWA Internal Security Review Auditors Desmond Ho, Lead Security Researcher Anurag Jain, Security Researcher CarrotSmuggler, Associate Security Researcher Report prepared by:Lucas Goiriz June 17, 2025 Contents 1 About Spearbit2 2 Introduction2 3 Risk classification2 3.1 Impact . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 3.2 Likelihood . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 3.3 Action required for severity levels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 4 Executive Summary3 5 Findings4 5.1 Medium Risk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 5.1.1GMTokenisn't redeemable due to lackingburn(uint256 amount)function . . . . . . . . . . .4 5.1.2QUOTE\_TYPEHASHis incorrectly defined . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 5.2 Low Risk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8 5.2.1 InconsistentgmIdentifierdefinition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8 5.2.2 MissingonUSDrefund on mints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9 5.3 Informational . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 5.3.1 Typos, Minor Recommendations, Redundancies . . . . . . . . . . . . . . . . . . . . . . . . . 10 5.3.2 Edge Cases & Technical Precautions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 5.3.3 Unrestricted minting without Rate limit allowed forADMIN\_MINT\_ROLE. . . . . . . . . . . . . . 13 1 1 About Spearbit Spearbit is a decentralized network of expert security engineers offering reviews and other security related services to Web3 projects with the goal of creating a stronger ecosystem. Our network has experience on every part of the blockchain technology stack, including but not limited to protocol design, smart contracts and the Solidity compiler. Spearbit brings in untapped security talent by enabling expert freelance auditors seeking flexibility to work on interesting projects together. Learn more about us at spearbit.com 2 Introduction Ondo's mission is to make institutional-grade financial products and services available to everyone. Disclaimer: This security review does not guarantee against a hack. It is a snapshot in time of Ondo RWA Internal according to the specific commit. Any modifications to the code will require a new security review. 3 Risk classification Severity levelImpact: HighImpact: MediumImpact: Low Likelihood: highCriticalHighMedium Likelihood: mediumHighMediumLow Likelihood: lowMediumLowLow 3.1 Impact • High - leads to a loss of a significant portion (>10%) of assets in the protocol, or significant harm to a majority of users. • Medium - global losses <10% or losses to only a subset of users, but still unacceptable. • Low - losses will be annoying but bearable--applies to things like griefing attacks that can be easily repaired or even gas inefficiencies. 3.2 Likelihood • High - almost certain to happen, easy to perform, or not easy but highly incentivized • Medium - only conditionally possible or incentivized, but still relatively likely • Low - requires stars to align, or little-to-no incentive 3.3 Action required for severity levels • Critical - Must fix as soon as possible (if already deployed) • High - Must fix (before deployment if not already deployed) • Medium - Should fix • Low - Could fix 2 4 Executive Summary Over the course of 7 days in total, Ondo Finance engaged with Spearbit to review the rwa-internal protocol. In this period of time a total of7issues were found. Summary Project NameOndo Finance Repositoryrwa-internal Commit88353254 Type of ProjectDeFi, Stablecoin Audit TimelineMay 28th to Jun 4th Issues Found SeverityCountFixedAcknowledged Critical Risk000 High Risk000 Medium Risk220 Low Risk220 Gas Optimizations000 Informational321 Total761 3 5 Findings 5.1 Medium Risk 5.1.1GMTokenisn't redeemable due to lackingburn(uint256 amount)function Severity:Medium Risk Context:GMToken.sol#L21, GMTokenManager.sol#L251-L257 Description:Redeeming GM tokens for RWA tokens will revert, because the redemption attempts to call burn(quote.quantity)on theGMToken, which it doesn't implement. Proof of Concept: diff --git a/forge-tests/globalMarkets/gmTokens/tokenDeployIntegration.t.sol b/forge-tests/globalMarkets/gmTokens/tokenDeployIntegration.t.sol,! index b763df1..c4d485c 100644 --- a/forge-tests/globalMarkets/gmTokens/tokenDeployIntegration.t.sol +++ b/forge-tests/globalMarkets/gmTokens/tokenDeployIntegration.t.sol @@ -29,6 +29,7 @@ contract GMTokenFactoryTest\_ETH is OUSG\_InstantManager\_BasicDeployment { OndoComplianceGMView public ondoComplianceGMView; TokenPauseManager public tokenPauseManager; GMTokenManager public gmTokenManager; + address public newGmToken; IssuanceHours public issuanceHours; onUSD public onusd; @@ -152,7 +153,7 @@ contract GMTokenFactoryTest\_ETH is OUSG\_InstantManager\_BasicDeployment { function test\_deployAndMintNewGMToken() public { vm.prank(OUSG\_GUARDIAN); - address newGmToken = gmTokenFactory.deployAndRegisterToken( + newGmToken = gmTokenFactory.deployAndRegisterToken( "Test GM Token", "TGT", OUSG\_GUARDIAN @@ -204,6 +205,41 @@ contract GMTokenFactoryTest\_ETH is OUSG\_InstantManager\_BasicDeployment { assertEq(onusd.totalSupply(), onUsdSupply - depositAmount); } + function test\_deployMintAndRedeemNewGMToken() public { + test\_deployAndMintNewGMToken(); + + uint256 rwaAmount = 1e18; + uint256 expiration = block.timestamp + 1 hours; + + // now do redemption + IGMTokenManager.Quote memory quote = IGMTokenManager.Quote({ + chainId: block.chainid, + attestationId: 2, + userId: aliceID, + asset: address(newGmToken), + price: 150e18, + quantity: rwaAmount, + expiration: expiration, + side: IGMTokenManager.QuoteSide.SELL, + additionalData: "" + }); + + // Create the attestation signature + bytes memory signature = \_createAttestation(attesterPrivateKey, quote); + 4 + // Approve manager to spend user's newGmToken + vm.startPrank(alice); + IERC20(newGmToken).approve(address(gmTokenManager), rwaAmount); + + + gmTokenManager.redeemWithAttestation( + quote, + signature, + address(onusd), + 0 + ); + } + function \_createAttestation( uint256 signerPrivateKey, IGMTokenManager.Quote memory quote Gets a generic revert because there isn't a function that matches the requested function selector when running forge test --mt test\_deployMintAndRedeemNewGMToken --rpc-url mainnet. The test passes after adding: function burn(uint256 amount) external { \_burn(msg.sender, amount); } Recommendation:HaveGMTokeninheritERC20BurnableUpgradeable(andIRWALIkeinterface), as it contains both theburn(uint256 amount)andburnFrom(address from, uint256 amount)functions. Also, as an optimi- sation,burnFrom()can be called instead ofsafeTransferFrom()andburn(). IRWALike(quote.asset).burnFrom(\_msgSender(), quote.quantity); Ondo Finance:Fixed in PR 432. Spearbit:Fix verified. 5.1.2QUOTE\_TYPEHASHis incorrectly defined Severity:Medium Risk Context:GMTokenManager.sol#L69, IGMTokenManager.sol#L48-L58 Description:The typehash is incorrect for enumQuoteSide, as it is converted touint8. By runningforge eip712 ./contracts/globalMarkets/tokenManager/IGMTokenManager.sol,we see that the expectant struct encoding isQuote(uint256 attestationId,uint256 chainId,bytes32 userId,uint8 side,address asset,uint256 price,uint256 quantity,uint256 expiration,bytes32 additionalData).As a result, signature verification will fail when the typehash is derived implicitly, eg. when signing using libraries likeviemor ethers. Proof of Concept:Go to thesignTypedDataexample on Viem (see signing typed-data), then replaceindex.tsx with: import React, { useState } from'react'; import ReactDOM from'react-dom/client'; import { type Address, type Hash, createWalletClient, custom } from'viem'; import { goerli } from'viem/chains'; import'viem/window'; const walletClient = createWalletClient({ chain: goerli, transport: custom(window.ethereum!), }); function Example() { 5 const \[account, setAccount\] = useState
} > ); return ; } ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( 6 ); Then we verify the signature created with Foundry. 2 test files: 1.SimpleVerifier.sol, inserted inglobalMarkets/mockfolder. // SPDX-License-Identifier: MIT pragma solidity 0.8.16; import "contracts/external/openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import "contracts/globalMarkets/tokenManager/IGMTokenManager.sol"; import "contracts/external/openzeppelin/contracts/utils/cryptography/EIP712.sol"; contract SimpleVerifier is EIP712 { bytes32 private constant QUOTE\_TYPEHASH = keccak256( "Quote(uint256 chainId,uint256 attestationId,bytes32 userId,address asset,uint256 price,uint256 quantity,uint256 expiration,uint8 side,bytes32 additionalData)",! ); constructor() EIP712("OndoGMTokenManager", "1") {} function verify(bytes calldata signature) public view returns (address signer) { IGMTokenManager.Quote memory quote = IGMTokenManager.Quote({ chainId: 1, attestationId: 1, userId: 0x48656c6c6f20576f726c64210000000000000000000000000000000000000000, asset: address(0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826), price: 1000000000, quantity: 1000000000, expiration: 1717000000, side: IGMTokenManager.QuoteSide.BUY, additionalData: 0x48656c6c6f20576f726c64210000000000000000000000000000000000000000 }); bytes32 digest = \_hashTypedDataV4( keccak256( abi.encode( QUOTE\_TYPEHASH, quote.chainId, quote.attestationId, quote.userId, quote.asset, quote.price, quote.quantity, quote.expiration, quote.side, quote.additionalData ) ) ); signer = ECDSA.recover(digest, signature); } } 2. Test verificationSimpleVerifier.t.sol: 7 // SPDX-License-Identifier: MIT pragma solidity 0.8.16; import "contracts/globalMarkets/mock/SimpleVerifier.sol"; import "forge-std/Test.sol"; contract VerifierTest is Test { SimpleVerifier verifier; function setUp() public { vm.chainId(1); verifier = new SimpleVerifier{salt: "test"}(); } function test\_verifySig() public { assertEq(address(verifier), 0xB565E44FA22A2497E38a70ee453B1be73a3d8Fc9, "incorrect verifier address derivation");// note that the address will change due to code changes, which affects the metadata appended ,! ,! bytes memory signature = hex"07a310b16b4071b1fbadc5fbda528f4eb3df7d00ce3a3ff015be0c35fdaa81c12e c cc6ceb814ebaf29bf60c0d447a9bb5323043eac62151f859142286e3cc7c901b";,! address signer = 0x91105527DCA5afBFc9A6c11260CE048C24c2078d; address recoveredSigner = verifier.verify(signature); assertEq(recoveredSigner, signer); } } Recommendation: • ModifyQUOTE\_TYPEHASH: - Quote(uint256 chainId,uint256 attestationId,bytes32 userId,address asset,uint256 price,uint256 quantity,uint256 expiration,QuoteSide side,bytes32 additionalData),! +\`Quote(uint256 chainId,uint256 attestationId,bytes32 userId,address asset,uint256 price,uint256 quantity,uint256 expiration,uint8 side,bytes32 additionalData),! • Modify theQuotestruct param order to matchQUOTE\_TYPEHASH: struct Quote { uint256 chainId; uint256 attestationId; bytes32 userId; address asset; uint256 price; uint256 quantity; uint256 expiration; QuoteSide side; bytes32 additionalData; } Ondo Finance:Fixed in PR 433. Spearbit:Fix verified. 5.2 Low Risk 5.2.1 InconsistentgmIdentifierdefinition Severity:Low Risk Context:OndoComplianceGMView.sol#L33-L34, GMTokenManager.sol#L60-L62 8 Description:gmIdentifierisdefinedasaddress(0x5ec);inOndoComplianceGMView, butaddress(uint160(uint256(keccak256(abi.encodePacked("global\_markets"))))); = 0x428ECB70E90d1527A5f5e177789f51747b883F34inGMTokenManager, which would cause confusion. Recommendation:Use the latter definition: - address public gmIdentifier = address(0x5ec); + address public gmIdentifier = address(uint160(uint256(keccak256(abi.encodePacked("global\_markets")))));,! Ondo Finance:Fixed in commit 33aecfb8. Spearbit:Fix verified. 5.2.2 MissingonUSDrefund on mints Severity:Low Risk Context:GMTokenManager.sol#L196-L206 Description:ThemintWithAttestationallows paying with tokens other thanonUSD. The issue is in that case, the user is charged the entire specified amountdepositTokenAmountinstead of the actual costmintOnusdValue. When minting with other tokens, the user's funds are first passed into theonUSDManagercontract, which mints temporaryonUSDtokens for the purchase. Suppose the user is using some token which can have a volatile exchange rate with respect toonUSDtokens. In that case, they will need to specify a higher then necessary input amount, in order to have their transaction go through reliably. These funds are then used to mintonUSDtokens, which are then burnt to mint the actual GM tokens. The price for the GM tokens is calculated in themintOnusdValuevariable. The contract only burnsmintOnusdValuevalue ofonUSDtokens, but does not pay out the remainder of the tokens. So if users specifydepositTokenAmountto be higher than the required amount to keep in mind the possible volatility of the payment token, they are charged the full amount even though they should only be chargedmintOnusdValueamount. Proof of Concept: diff --git a/forge-tests/globalMarkets/tokenManager/GMTokenManagerPSMIntegrationTest.t.sol b/forge-tests/globalMarkets/tokenManager/GMTokenManagerPSMIntegrationTest.t.sol,! index d480e39..2988795 100644 --- a/forge-tests/globalMarkets/tokenManager/GMTokenManagerPSMIntegrationTest.t.sol +++ b/forge-tests/globalMarkets/tokenManager/GMTokenManagerPSMIntegrationTest.t.sol @@ -251,9 +251,9 @@ contract onUSDManagerTest\_ETH is OUSG\_InstantManager\_BasicDeployment { bytes memory signature = \_createAttestation(attesterPrivateKey, quote); // Approve manager to spend user's onUSD - deal(address(USDC), user, usdcDepositAmount); + deal(address(USDC), user, 2 \* usdcDepositAmount); vm.startPrank(user); - USDC.approve(address(gmTokenManager), usdcDepositAmount); + USDC.approve(address(gmTokenManager), 2 \* usdcDepositAmount); // Token supply before subscription/burn uint256 onUsdSupply = onusd.totalSupply(); @@ -262,7 +262,7 @@ contract onUSDManagerTest\_ETH is OUSG\_InstantManager\_BasicDeployment { quote, signature, address(USDC), - usdcDepositAmount + 2 \* usdcDepositAmount ); vm.stopPrank(); Output tokens remain the same even though the input USDC amount doubles. 9 Recommendation:As long asonUSDand thedepositTokenare maintaining their peg, onlymintOnusdValue amount of tokens should be charged (for a 1:1 peg). For unpeggeddepositToken, consider refunding the unused amount ofonUSDtokens. uint256 depositedOnusdValue = onUSDManager.subscribe( depositToken, depositTokenAmount, mintOnusdValue ); uint256 refund = depositedOnusdValue - mintOnusdValue; Ondo Finance:Fixed in PR 435. Spearbit:Fix verified. 5.3 Informational 5.3.1 Typos, Minor Recommendations, Redundancies Severity:Informational Context:OndoComplianceGMClientUpgradeable.sol#L98, IssuanceHours.sol#L33, IssuanceHours.sol#L60, IssuanceHours.sol#L72-L83,IssuanceHours.sol#L90-L94,onUSDFactory.sol#L116-L138,IonUSDMan- agerEvents.sol#L17, onUSD.sol#L59, OndoSanityCheckOracle.sol#L169, OndoSanityCheckOracle.sol#L180- L186, GMTokenFactory.sol#L188-L194, GMTokenFactory.sol#L231-L234, IGMTokenManagerEvents.sol#L40-L43, TokenPauseManagerClientUpgradeable.sol#L100 Description / Recommendation: • Typos: - accepred + accepted - Easter + Eastern - UTC-5 (5 \* 3600) or UTC-4 (4 \* 3600) + UTC-5 (-5 \* 3600) or UTC-4 (-4 \* 3600) • Minor Recommendations: –Consider using BokkyPooBahDateTimeLibrary's implementation for obtaining the day of the week, which was formally verified by Zellic. The main difference is that Sunday is counted as7instead of 0here, so the check is simpler as well. function checkIsValidHours() external view { // Computes the day of the week based on the current block timestamp // Ref: BokkyPooBahDateTimeLibrary's\`getDayOfWeek()\`implementation uint8 dayOfTheWeek = uint8( ((\_abs(int256(block.timestamp) + timezoneOffset)) / DAY\_IN\_SECONDS + 3) % 7 + 1 ); // 6 = Saturday, 7 = Sunday if (dayOfTheWeek > 5) { revert OutsideMarketHours(); } } 10 –Consider capping the offset to -12 hours / +14 hours from UTC: + error MaximumOffsetExceeded(); function setTimezoneOffset(int256 \_timezoneOffset) public onlyOwner { + if(\_timezoneOffset < -12 \* HOUR\_IN\_SECONDS || \_timezoneOffset > 14 \* HOUR\_IN\_SECONDS) revert MaximumOffsetExceeded();,! emit SetTimezoneOffset(timezoneOffset, \_timezoneOffset); timezoneOffset = \_timezoneOffset; } –Modify the slot gaps forOndoComplianceGMClientUpgradeableandTokenPauseManagerClientUp- gradeableto be 1 less each, so the offset stays consistent: - uint256\[50\] private \_\_gap; + uint256\[49\] private \_\_gap; –Sanity check thatbps/minimumLivenessisn't 0 insetDefaultAllowedDeviationBps()/setMinimum- Liveness()respectively, as: 1. Practically it doesn't make sense to have zero price deviation / liveness. 2. Would always be emitting theAllowedDeviationSet()andAllowedDeviationSetevents when posting prices. –ModifysetTokenPauseManager()to be consistent with other setters: if (\_tokenPauseManager == address(0)) revert TokenPauseManagerCantBeZero(); emit NewTokenPauseManagerSet(tokenPauseManager, \_tokenPauseManager); tokenPauseManager = \_tokenPauseManager; –GMTokenFactory.solmisses to implementIGMTokenPad.solinterface. –Consider using the beacon proxy pattern forGMTokendeployments, since there are expected to be hundreds or thousands of instances deployed. More information can be found in this Rareskills article and in the OpenZeppelin foundry upgrades plugin documentation. • Redundancies: –Granting theDEFAULT\_ADMIN\_ROLEtomsg.senderis redundant in\_\_onUSD\_init\_unchainedas\_\_- ERC20PresetMinterPauser\_init\_unchainedwill already do it. - grantRole(DEFAULT\_ADMIN\_ROLE, msg.sender); –multiexcall()inonUSDFactoryis redundant because it only has 1 callable function that can be exe- cuted just once. –IonUSDManagerEventsandIonUSDManagerErrorsare defined but unused. –TheIGMTokenManagerEvents.OndoComplianceSetevent is defined but unused. Ondo Finance: • Fix typos, limit offset and utilize BokkyPooBahDateTimeLibrary. • Sanity check oracle, disable 0 bps deviation and liveliness. • Remove default admin role grant from onusd init unchained. • Remove unused interfaces and events. • Remove multiexcall from factory. • Updated token pause logic, errors, and events. • ImplementIGMTokenPad(renamed toIGMTokenFactory) and haveGMTokenFactoryinherit it. 11 • Updated slot gaps. • Beacon proxy pattern forGMToken. •accepred->acceptedtypo fix. Spearbit:Fix verified. 5.3.2 Edge Cases & Technical Precautions Severity:Informational Context:GMToken.sol#L79-L80, GMToken.sol#L138-L153, IssuanceHours.sol#L72, onUSDManager.sol#L59, OndoSanityCheckOracle.sol#L166-L173, TokenManagerRegistrar.sol#L152-L153 Description/Recommendation: • onUSDManager.sol#L59: –OnUSDpoints toOndoComplianceGMViewto get compliance. –onUSDManagerusesBaseRWAManagerwhich directly points to compliance address. –Thus, if compliance address is ever changed foronUSD, change in bothOndoComplianceGMViewand BaseRWAManager. • TokenManagerRegistrar.sol#L152: –While changinggmTokenManager, minter role is not revoked from oldgmTokenManager(due to migration support). –Ensure that minter role is removed manually from oldgmTokenManager. • OndoSanityCheckOracle.sol: –Default Deviation changes will be applicable only for newly introduced tokens as existing tokens would already be set with olddefaultDeviationBpsor customallowedDeviationBps. In case existing to- kens deviation bps also require updation from old default value then it need to be done for each token individually. –Same goes forminimumLivenessset viasetDefaultMinimumLiveness. • IssuanceHours.sol#L72: –The system incorrectly permits trading on days when the stock market is closed due to festival holidays. –Note: As confirmed by Ondo team, after-hours trading is allowed overnight on trading day. • GMToken.sol#L138-L153: –Ideally unpausing should only be allowed byUNPAUSE\_TOKEN\_ROLEbutCONFIGURER\_ROLEcan simply change Pause Manager usingsetTokenPauseManagerand can unpause contracts. –If not expected then do not allow changing Pause Manager if contract is in paused state. • GMToken.sol: The current implementation does not pose any immediate issues, but we should keep the following in mind: 1. Future Changes to\_\_TokenPauseManagerClientInitializable\_init: –If this function is updated in the future to include initialization of additional base contracts, we might need to switch to calling the full\_\_TokenPauseManagerClientInitializable\_initinstead of the \_unchained version to ensure proper initialization. 2. Addition of New Base Contracts: –If a new base class is added that also calls\_\_OndoComplianceGMClientInitializable\_init, it could result in double initialization. In such cases, we would need to carefully manage initializer calls, possibly by relying on the \_unchained variant to avoid reinitializing the same base contract more than once. 12 Ondo Finance:Acknowledged. Spearbit:Acknowledged. 5.3.3 Unrestricted minting without Rate limit allowed forADMIN\_MINT\_ROLE Severity:Informational Context:GMTokenManager.sol#L304-L317 Description:It was observed that: •ADMIN\_MINT\_ROLEcan mint as much GMTokens as they want without any upper cap and rate limit using adminProcessMintfunction. • AlsoadminProcessMintfunction does not have pause restrictions which meansADMIN\_MINT\_ROLEcan mint even when contract is paused for minting. Recommendation: 1. Add rate limits so thatADMIN\_MINT\_ROLEcan only mint till allowed cap. 2. AddwhenMintingNotPausedif minting is not expected even withADMIN\_MINT\_ROLEonce minting is paused. Ondo Finance:Fixed in PR 434. Spearbit:Fix verified. 13
---
# Unknown
Ondo Global Markets Audit Report Prepared by Cyfrin Version 2.0 Lead Auditors Immeas Al-Qa'qa' July 14, 2025 Contents 1 About Cyfrin2 2 Disclaimer2 3 Risk Classification2 4 Protocol Summary2 4.1 Actors and Roles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 4.2 Key Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 4.3 Centralization Risks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 5 Audit Scope3 6 Executive Summary3 7 Findings5 7.1 Low Risk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 7.1.1 guardian missing PAUSER\_ROLE grant in onUSD deployment . . . . . . . . . . . . . . . . . . .5 7.1.2 Compliance check discrepancy between onUSDManager and onUSD transfers . . . . . . . . . .5 7.2 Informational . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7 7.2.1 OndoSanityCheckOracle::setAllowedDeviationBps is not checking zero value as input which will introduce problems using it . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7 7.2.2 Inconsistent unpause role in onUSD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7 7.2.3 GMTokenManager::mintWithAttestation breaks Check-Effects-Interactions pattern . . . . .7 7.2.4 Inconsistent role for GMTokenManager::setIssuanceHours . . . . . . . . . . . . . . . . . . .8 7.2.5 Unnecessary boolean comparisons in GMTokenManager . . . . . . . . . . . . . . . . . . . . .8 7.2.6 Inconsistent type usage for IssuanceHours.HOUR\_IN\_SECONDS . . . . . . . . . . . . . . . . .8 7.2.7 Confusing field name minimumLiveness in PriceData struct . . . . . . . . . . . . . . . . . . .8 7.2.8 Test enhancements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8 7.2.9 Natspec enhancements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9 7.2.10 Missing nonReentrant modifier on GMTokenManager mint/redeem . . . . . . . . . . . . . . . .9 1 1 About Cyfrin Cyfrin is a Web3 security company dedicated to bringing industry-leading protection and education to our partners and their projects. Our goal is to create a safe, reliable, and transparent environment for everyone in Web3 and DeFi. Learn more about us at cyfrin.io. 2 Disclaimer The Cyfrin team makes every effort to find as many vulnerabilities in the code as possible in the given time but holds no responsibility for the findings in this document. A security audit by the team does not endorse the underlying business or product. The audit was time-boxed and the review of the code was solely on the security aspects of the solidity implementation of the contracts. 3 Risk Classification Impact: HighImpact: MediumImpact: Low Likelihood: HighCriticalHighMedium Likelihood: MediumHighMediumLow Likelihood: LowMediumLowLow 4 Protocol Summary Ondo Global Markets is a new product by Ondo that enables users to tokenize publicly traded securities on-chain. KYC’d users can interact with Ondo to purchase GMTokens, which are tokenized representations of real-world securities. These tokens can then be freely traded on-chain. However, GMTokens can only be minted or burned during normal trading hours (24/5). The system also introduces a stablecoin, USDon, which represents cash held by Ondo at a brokerage. This is the token used to purchase securities. A dedicated contract, usdonManager, facilitates swaps into USDon from supported stablecoins (e.g., USDC). To enhance safety, the protocol includes a sanity check oracle, which ensures that prices for securities do not deviate significantly from a previously posted reference price. This prevents malicious or erroneous off-chain input from resulting in incorrect or unbacked token mints. 4.1 Actors and Roles 1. Actors • Off-chain service: Executes the actual buying and selling of real-world securities. Signs attestations for minting and redeeming. • Ondo team: Manages contracts, updates configurations, and oversees system integrity. • Users: Must complete KYC to participate. Once approved, they can buy and sell tokenized securities. 2. Roles • DEFAULT\_ADMIN\_ROLE: Grants/revokes all other roles and manages system-level configuration. • CONFIGURER\_ROLE: Configures protocol parameters and contract references. • DEPLOYER\_ROLE: Deploys new GMTokens. 2 • ATTESTATION\_SIGNER\_ROLE: Signs EIP-712-compliant attestations for mint/redeem operations. Must be held by an EOA. • MINTER\_ROLE: Allows minting of GMTokens and USDon. Held by GMTokenManager and usdonManager. • BURNER\_ROLE: Allows burning of GMTokens and USDon. Held by GMTokenManager and usdonManager. • PAUSER\_ROLE / PAUSE\_TOKEN\_ROLE: Authorized to pause contracts and token transfers. • UNPAUSER\_ROLE / UNPAUSE\_TOKEN\_ROLE: Authorized to unpause contracts and token transfers. • TOKEN\_FACTORY\_ROLE: Used by GMTokenFactory to deploy new token contracts. 4.2 Key Components • USDon: A stablecoin backed by cash held at a brokerage. It can only be held or transferred by compliant (non-OFAC) users. It is pausable. • usdonManager: An RWAManager contract that enables users to swap supported stablecoins into USDon. • GMTokens: Tokenized representations of public securities. Can only be held or transferred by compliant users. Pausable for safety via a shared mechanism in TokenPauseManager, which can pause or unpause all tokens globally or individually. • GMTokenManager: Manages the buying and selling of GMTokens. Integrates with usdonManager to allow swaps from other stablecoins into USDon. Enforces compliance, trading hour restrictions (24/5), and sanity- checked pricing to prevent deviation from posted oracle prices. 4.3 Centralization Risks These contracts are heavily managed by the Ondo team, so using this protocol requires a high level of trust in Ondo’s operational security. If Ondo’s privileged wallets were ever compromised, the consequences could be catastrophic for the protocol. Extreme care must be taken to safeguard admin keys and related infrastructure. 5 Audit Scope All files under contracts/globalMarkets: contracts/globalMarkets/GMTokenCompliance/OndoComplianceGMClientUpgradeable.sol contracts/globalMarkets/GMTokenCompliance/OndoComplianceGMView.sol contracts/globalMarkets/issuanceHours/IssuanceHours.sol contracts/globalMarkets/onUSDManager/onUSDManager.sol contracts/globalMarkets/sanityCheckOracle/OndoSanityCheckOracle.sol contracts/globalMarkets/tokenFactory/GMTokenFactory.sol contracts/globalMarkets/tokenManager/GMTokenManager.sol contracts/globalMarkets/tokenPauseManager/TokenPauseManager.sol contracts/globalMarkets/tokenPauseManager/TokenPauseManagerClientUpgradeable.sol contracts/globalMarkets/BridgeRegistrarStub.sol contracts/globalMarkets/GMToken.sol contracts/globalMarkets/onUSD.sol contracts/globalMarkets/onUSDFactory.sol contracts/globalMarkets/TokenManagerRegistrar.sol 6 Executive Summary Over the course of 10 days, the Cyfrin team conducted an audit on the Ondo Global Markets smart contracts provided by Ondo. In this period, a total of 12 issues were found. 3 The audit uncovered two low-severity issues: The first involved a missing role grant during the deployment of USDon. The second concerned a discrepancy between the compliance check used when minting/redeeming USDon and the one used during token transfers. Several informational findings were also identified, covering best practices, code quality, and opportunities for improvement in testing and documentation. During the audit, the team renamed the USD stablecoin from onUSD to USDon. This change was introduced in commit 85d5b09 and was deemed safe. The Cyfrin team also contributed test enhancements, included in commit d3155d0. Summary Project NameOndo Global Markets Repositoryrwa-internal Commita74d03f4a71b. . . Audit TimelineJul 1st - Jul 14th, 2025 MethodsManual Review Issues Found Critical Risk0 High Risk0 Medium Risk0 Low Risk2 Informational10 Gas Optimizations0 Total Issues12 Summary of Findings \[L-1\] guardian missing PAUSER\_ROLE grant in onUSD deploymentResolved \[L-2\] Compliance check discrepancy between onUSDManager and onUSD trans- fers Acknowledged \[I-1\] OndoSanityCheckOracle::setAllowedDeviationBps is not checking zero value as input which will introduce problems using it Resolved \[I-2\] Inconsistent unpause role in onUSDResolved \[I-3\] GMTokenManager::mintWithAttestationbreaksCheck-Effects- Interactions pattern Resolved \[I-4\] Inconsistent role for GMTokenManager::setIssuanceHoursResolved \[I-5\] Unnecessary boolean comparisons in GMTokenManagerResolved 4 \[I-6\] Inconsistent type usage for IssuanceHours.HOUR\_IN\_SECONDSResolved \[I-7\] Confusing field name minimumLiveness in PriceData structResolved \[I-8\] Test enhancementsResolved \[I-9\] Natspec enhancementsResolved \[I-10\] Missing nonReentrant modifier on GMTokenManager mint/redeemResolved 5 7 Findings 7.1 Low Risk 7.1.1 guardian missing PAUSER\_ROLE grant in onUSD deployment Description: Deployment of the onUSD token is handled via the onUSDFactory, which sets up the token as an upgradeable proxy using the transparent proxy pattern (EIP-1967). As documented in the contract comments, the guardian address is expected to be granted both the DEFAULT\_- ADMIN\_ROLE and PAUSER\_ROLE: globalMarkets/onUSDFactory.sol#L33-36 /\*\* ... \* Following the above mentioned deployment, the address of the onUSD\_Factory contract will: \* i) Grant the\`DEFAULT\_ADMIN\_ROLE\` & PAUSER\_ROLE to the\`guardian\` address <<---------------- \* ii) Revoke the\`MINTER\_ROLE\`,\`PAUSER\_ROLE\` &\`DEFAULT\_ADMIN\_ROLE\` from address(this). \* iii) Transfer ownership of the ProxyAdmin to that of the\`guardian\` address. \*/ However, in the actual deployment logic, only the DEFAULT\_ADMIN\_ROLE is granted to the guardian. The PAUSER\_- ROLE is omitted: globalMarkets/onUSDFactory.sol#L88 function deployonUSD( ... ) external onlyGuardian returns (address, address, address) { ... // @audit\`PAUSER\_ROLE\` not granted to guardian >> onusdProxied.grantRole(DEFAULT\_ADMIN\_ROLE, guardian); onusdProxied.revokeRole(MINTER\_ROLE, address(this)); onusdProxied.revokeRole(PAUSER\_ROLE, address(this)); onusdProxied.revokeRole(DEFAULT\_ADMIN\_ROLE, address(this)); onusdProxyAdmin.transferOwnership(guardian); assert(onusdProxyAdmin.owner() == guardian); initialized = true; emit onUSDDeployed( ... ); return ( ... ); } As a result, deployment completes without the guardian address having the PAUSER\_ROLE in the onUSD token contract, contrary to the intended and documented behavior. Impact: The guardian will not have the PAUSER\_ROLE in the deployed onUSD token contract. This prevents them from pausing the token immediately after deployment, potentially limiting their ability to respond to emergencies or enforce compliance controls. However, since the guardian retains the DEFAULT\_ADMIN\_ROLE, they can manually grant themselves the PAUSER\_ROLE later. Still, this deviates from the intended one-step initialization flow and introduces the risk of operational oversight. Recommended Mitigation: Grant the PAUSER\_ROLE to the guardian address immediately after assigning the DEFAULT\_ADMIN\_ROLE, to match both the contract’s intended behavior and its documentation: onusdProxied.initialize(name, ticker, complianceView); onusdProxied.grantRole(DEFAULT\_ADMIN\_ROLE, guardian); + onusdProxied.grantRole(PAUSER\_ROLE, guardian); onusdProxied.revokeRole(MINTER\_ROLE, address(this)); 6 onusdProxied.revokeRole(PAUSER\_ROLE, address(this)); Ondo: Fixed in commit b13a651. It's the comment that is incorrect here - we only want to grant the default admin role, as it is temporarily used by the deployment EOA to configure the contract properly. Once configured, the default admin is renounced. If the pauser was also granted to the EOA on deployment it would just require another call to renounce Cyfrin: Verified. Comment removed. 7.1.2 Compliance check discrepancy between onUSDManager and onUSD transfers Description: When minting or redeeming onUSD via onUSDManager, the contract extends BaseRWAManager, which performs a compliance check using the onUSD token address (address(onUSD)) as the rwaToken identifier. This happens in BaseRWAManager::\_processSubscription: // Reverts if user address is not compliant ondoCompliance.checkIsCompliant(rwaToken, \_msgSender()); The same check occurs during redemptions via BaseRWAManager::\_processRedemption. Separately, the onUSD token contract itself performs compliance checks inside onUSD::\_beforeTokenTransfer, which is invoked during transfers, minting, and burning. This function calls the inherited OndoComplianceGMClien- tUpgradeable::\_checkIsCompliant, which delegates to OndoComplianceGMView::checkIsCompliant: function checkIsCompliant(address user) external override { compliance.checkIsCompliant(gmIdentifier, user); } Here, OndoComplianceGMViewgmIdentifier is a hardcoded address derived from the string "global\_markets" and used as the rwaToken identifier: address public gmIdentifier = address(uint160(uint256(keccak256(abi.encodePacked("global\_markets"))))); As a result, minting and redeeming will trigger two compliance checks with different identifiers: • address(onUSD) via the manager logic • gmIdentifier via the token's \_beforeTokenTransfer Impact: Although \_beforeTokenTransfer runs during minting and burning, meaning both compliance checks still occur, the use of two different rwaToken identifiers introduces an unnecessary inconsistency. If the two compliance lists are not aligned, minting or redeeming could revert unexpectedly, despite the user being compliant under one identifier. Recommended Mitigation: There are two possible mitigation approaches, depending on which compliance iden- tifier is intended as canonical for onUSD. 1) Update OnUSD::\_beforeTokenTransfer to explicitly use address(this) as the rwaToken in all compliance checks. This aligns the transfer/mint/burn logic with the identifier used in the manager’s mint/redeem flow, ensuring consistency and eliminating the need to maintain two separate compliance lists. if (from != msg.sender && to != msg.sender) { compliance.checkIsCompliant(address(this), msg.sender); } if (from != address(0)) { // If not minting compliance.checkIsCompliant(address(this), from); } if (to != address(0)) { // If not burning 7 compliance.checkIsCompliant(address(this), to); } 2) If gmIdentifier is intended to serve as a shared compliance identity for global markets assets (including onUSD), consider using gmIdentifier in the onUSDManager mint/redeem flow as well. This would unify all compliance checks under a single identifier, reducing operational fragmentation. Ondo: Acknowledged. The OndoCompliance check in the USDonManager only exists due to the USDonManager inheriting the BaseRWAManager - since the check already exists in USDon transfers themselves it would be completely redundant if used. Knowing this, we will leave the sanctions and blocklist unset for USDon in OndoCompliance so that the checks coming from the USDonManager are effectively bypassed, and we instead rely on checks stemming from USDon transfers themselves and keyed on the gmIdentifier. 8 7.2 Informational 7.2.1 OndoSanityCheckOracle::setAllowedDeviationBps is not checking zero value as input which will introduce problems using it Description: In OndoSanityCheckOracle, there are two types of deviation values: a default deviation applied to all tokens by default, and a token-specific deviation set per asset via setAllowedDeviationBps(). The default deviation value is validated to be non-zero, while token-specific deviations can be set to zero: OndoSanityCheckOracle.sol#L222-L245 function setAllowedDeviationBps(...) external onlyRole(CONFIGURER\_ROLE) { if (bps >= BPS\_DENOMINATOR) revert InvalidDeviationBps(); prices\[token\].allowedDeviationBps = bps; emit AllowedDeviationSet(token, bps); } function setDefaultAllowedDeviationBps(...) public onlyRole(CONFIGURER\_ROLE) { if (bps == 0) revert InvalidDeviationBps(); // enforced here if (bps >= BPS\_DENOMINATOR) revert InvalidDeviationBps(); emit DefaultAllowedDeviationSet(defaultDeviationBps, bps); defaultDeviationBps = bps; } Setting a token deviation to zero is functionally meaningless, however, because zero is interpreted as “use the default” during price posting: OndoSanityCheckOracle.sol#L189-L192 if (priceData.allowedDeviationBps == 0) { priceData.allowedDeviationBps = defaultDeviationBps; emit AllowedDeviationSet(token, priceData.allowedDeviationBps); } This creates a subtle inconsistency: the contract accepts 0 as a valid input for per-token deviations, but the value will be ignored and overridden when posting a price. If zero deviation is considered too strict or unsupported, enforce a bps > 0 check in setAllowedDeviationBps(), mirroring the validation in setDefaultAllowedDevia- tionBps(). Alternatively, if 0 is meant to indicate “use default,” consider introducing an explicit boolean field to track whether a token’s deviation has been explicitly set, rather than relying on 0 as a sentinel value. Ondo: Fixed in commit 6a33346 Cyfrin: Verified. allowedDeviationBps is not allowed to be 0. 7.2.2 Inconsistent unpause role in onUSD Description: onUSD::unpause is restricted to DEFAULT\_ADMIN\_ROLE, unlike other contracts in the system that use a dedicated UNPAUSER\_ROLE. This breaks consistency in access control design and limits flexibility in delegating unpause authority: function unpause() public override onlyRole(DEFAULT\_ADMIN\_ROLE) { \_unpause(); } Consider using UNPAUSER\_ROLE for onUSD::unpause to align with the pattern used across other contracts. Ondo: Fixed in commit 650c527 Cyfrin: Verified.UNPAUSER\_ROLE used in USDon::unpause (renamed) 9 7.2.3 GMTokenManager::mintWithAttestation breaks Check-Effects-Interactions pattern Description: In GMTokenManager::mintWithAttestation, the function transfers tokens from the user before per- forming internal accounting operations such as rate limiting, burning, and minting. This violates the check-effects- interactions pattern, where external calls (like token transfers) should typically come after all internal state updates to reduce risk. While the token being transferred is assumed to be a trusted stablecoin, this ordering increases the surface area for unexpected behavior if any integrated token misbehaves (e.g., via callback hooks, pausable logic, or fee-on- transfer behavior). Considerreorderingoperationsin mintWithAttestationtofollowthecheck-effects-interactions pattern—performing rate limiting, burns, and mints before calling token.transferFrom(). Ondo: Fixed in commit 29bdeb9 Cyfrin: Verified. rate limiting now done before external calls. 7.2.4 Inconsistent role for GMTokenManager::setIssuanceHours Description: The GMTokenManager::setIssuanceHours function is restricted to CONFIGURER\_ROLE, whereas other configuration and role assignment functions across the system are typically restricted to DEFAULT\_ADMIN\_ROLE. This inconsistency may cause confusion about which roles are responsible for governance and configuration actions. Consider aligning access control by restricting setIssuanceHours to DEFAULT\_ADMIN\_ROLE, consistent with similar configuration functions elsewhere. Ondo: Fixed in commit 3d18299 Cyfrin: Verified. DEFAULT\_ADMIN\_ROLE is now used for GMTokenManager::setIssuanceHours. 7.2.5 Unnecessary boolean comparisons in GMTokenManager Description: Both in GMTokenManager::\_verifyQuote#L329 and GMTokenManager::adminProcessMint#L389 there's a boolean comparison: if (gmTokenAccepted\[gmToken\] == false) revert GMTokenNotRegistered(); This is redundant. Consider simplifying it to: if (!gmTokenAccepted\[gmToken\]) revert GMTokenNotRegistered(); Ondo: Fixed in commit 1877211 Cyfrin: Verified. 7.2.6 Inconsistent type usage for IssuanceHours.HOUR\_IN\_SECONDS Description: In IssuanceHours the constant IssuanceHours.HOUR\_IN\_SECONDS field is declared as uint, while the rest of the codebase consistently uses uint256: /// Constant for the number of seconds in an hour uint constant HOUR\_IN\_SECONDS = 3\_600; Consider updating the field to use uint256 to align with the project's standard type declarations. Ondo: Fixed in commit fe452a1 Cyfrin: Verified. HOUR\_IN\_SECONDS uses type int256 (since that removes a cast in \_validateTimezoneOffset) 10 7.2.7 Confusing field name minimumLiveness in PriceData struct Description: The PriceData struct in OndoSanityCheckOracle includes a field named minimumLiveness, which actually represents the maximum age a price can be before it's considered stale. The current name may be misleading, as "minimum liveness" implies a lower bound on freshness rather than an upper bound on staleness. Consider renaming the field to something clearer like maxPriceAge or staleThreshold to better reflect its purpose and improve code readability. Ondo: Fixed in commits b453b57 and 9af9735 Cyfrin: Verified. Renamed to maxTimeDelay. 7.2.8 Test enhancements Description: \* GMIntegrationTest\_GM\_ETH: Both tests test\_hitRateLimits\_onUSDInGMFlow\_Subscribe and test\_hitRateLimits\_onUSDInGMFlow\_Redeem have empty expectReverts: // Should fail due to onUSD rate limit vm.expectRevert(); gmTokenManager.mintWithAttestation( quote, signature, address(USDC), usdcAmount ); Accepting any revert could hide unexpected errors allowing bugs to still pass the tests. Consider catching the expected revert: // Should fail due to onUSD rate limit - vm.expectRevert(); + vm.expectRevert(OndoRateLimiter.RateLimitExceeded.selector); gmTokenManager.mintWithAttestation( quote, signature, address(USDC), usdcAmount ); • GmTokenManagerSanityCheckOracleTest: The test testPostPricesWithInvalidInput also has an empty expectRevert(). This test should ideally be split into two, ...WithInvalidToken, ...WithInvalidPrice and expect the correct errors: InvalidAddress and PriceNotSet. • error TokenPauseManagerClientUpgradeable.TokenPauseManagerCantBeZero lacks a test.Consider adding one for assigning an invalid TokenPauseManager. • GMTokenManagerTest\_ETH: The test testMintFromNonKYCdSender mentions a "KYC role" which doesn't exist. It also catches an empty revert on L626. This catch does not catch the correct error, it catches a OneRate- Limiter.RateLimitExceeded error since the user has no rate limit config. Since the user is added to the registry on L601, effectively saying it's KYC'd. Thus it passes the KYC check. Consider removing mentions of a KYC role, catching the correct revert (IGMTokenManagerErrors.UserNotRegistered) and remove the addition of the user to the registry. Cyfrin: Fixed by Cyfrin in commit d3155d0 7.2.9 Natspec enhancements Description: \* onUSD\_Factory::deployonUSD is missing the complianceView parameter in its natspec. • onUSD\_Factory.onUSDDeployed event is missing parameters name, ticker, and complianceView • GMTokenManager::constructor is missing \_onUsd parameter 11 • GMTokenManager::adminProcessMint is missing gmToken parameter • TokenPauseManager::unpauseAllTokens:thetext Only affects tokens paused by the pauseAllTokens function could be worded better as this is all tokens. Ondo: Fixed in commit d7dc414 Cyfrin: Verified. 7.2.10 Missing nonReentrant modifier on GMTokenManager mint/redeem Description: The GMTokenManager::mintWithAttestation and GMTokenManager::redeemWithAttestation functions perform external token transfers and internal state updates but do not use the nonReentrant modifier. While GMTokenManager inherits from OpenZeppelin's ReentrancyGuard, which is currently unused, the modifier is not applied to these functions. Consider adding the nonReentrant modifier to mintWithAttestation and redeemWithAttestation. Ondo: Fixed in commit d7dc414 Cyfrin: Verified. 12
---
# Smart Contract Audits | Ondo Finance
Smart Contract Audits
Smart Contract Audits
=====================
Our smart contracts have successfully completed audits from some of the leading firms in the industry.
You can find our audit reports linked below:
**Ondo Global Markets**
* [June 2025 Spearbit Audit](https://docs.ondo.finance/pdf/report-cantinacode-ondo-0224-2.pdf)
* [July 2025 Cyfrin Audit](https://docs.ondo.finance/pdf/2025-07-14-cyfrin-ondo-global-markets-v2.0.pdf)
* [October 2025 Cantina Audit (opens in a new tab)](https://cantina.xyz/portfolio/91210482-130b-478a-848c-773029679a90)
**Ondo Funds and USDY (Ethereum)**
* [March 2025 Spearbit Audit (opens in a new tab)](https://cantina.xyz/portfolio/fb329103-8bd1-45ac-91d8-4f75e1abf812)
* [February 2025 Halborn Audit](https://docs.ondo.finance/pdf/Ondo-Halborn-Audit-Feb-2025.pdf)
* [April 2024 Code4rena Audit (opens in a new tab)](https://code4rena.com/reports/2024-03-ondo-finance)
* [April 2024 Cyfrin Audit](https://docs.ondo.finance/pdf/Ondo-Cyfrin-Audit-April-2024.pdf)
* [September 2023 Code4rena Audit (opens in a new tab)](https://code4rena.com/reports/2023-09-ondo/)
* [August 2023 Zokyo Audit](https://docs.ondo.finance/pdf/Ondo-Zokyo-Audit-August-2023.pdf)
* [April 2023 NetherMind Audit](https://docs.ondo.finance/pdf/Ondo-NetherMind-Audit-April-2023.pdf)
* [January 2023 Code4rena Audit (opens in a new tab)](https://code4rena.com/reports/2023-01-ondo/)
**Ondo Funds and USDY (Noble)**
* [June 2024 Halborn Audit](https://docs.ondo.finance/pdf/Ondo-Halborn-Audit-June-2024.pdf)
* [July 2024 Halborn Audit (additional module)](https://docs.ondo.finance/pdf/Ondo-Halborn-Additional-Aura-Module-Audit-June-2024.pdf)
**Deprecated Ondo Products**
* [May 2022 ABDK Audit](https://docs.ondo.finance/pdf/Ondo-ABDK-Audit-October-2022.pdf)
* [January 2022 Quantstamp Audit](https://docs.ondo.finance/pdf/Ondo-Quantstamp-Audit-January_2022.pdf)
* [September 2021 Quantstamp Audit](https://docs.ondo.finance/pdf/Ondo-Quantstamp-Audit-September_2021.pdf)
* [May 2021 Peckshield Audit](https://docs.ondo.finance/pdf/Ondo-Peckshield-Audit-May_2021.pdf)
* [April 2021 Certik Audit](https://docs.ondo.finance/pdf/Ondo-Certik-Audit-April_2021.pdf)
[Smart Contract Addresses](https://docs.ondo.finance/addresses "Smart Contract Addresses")
[Ondo V1 - Vaults & LaaS](https://docs.ondo.finance/ondo-v1-vaults-laas "Ondo V1 - Vaults & LaaS")
---
# Unknown
Ondo Finance Audit Report Prepared by Cyfrin Version 2.0 Lead Auditor Dacian April 18, 2024 Contents 1 About Cyfrin2 2 Disclaimer2 3 Risk Classification2 4 Protocol Summary2 5 Audit Scope3 6 Executive Summary3 7 Findings6 7.1 Low Risk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6 7.1.1InvestorBasedRateLimiter::setInvestorMintLimitandsetInvestorRe- demptionLimitcanmakesubsequentcallstocheckAndUpdateMintLimitand checkAndUpdateRedemptionLimitrevert due to underflow . . . . . . . . . . . . . . . . . . .6 7.1.2 Prevent creating an investor record associated with the zero address . . . . . . . . . . . . . .7 7.1.3 Prevent creating an investor record associated with no address . . . . . . . . . . . . . . . . .7 7.1.4InstantMintTimeBasedRateLimiter::\_setInstantMintLimitand\_setInstantRe- demptionLimitcan make subsequent calls to\_checkAndUpdateInstantMintLimitand \_checkAndUpdateInstantRedemptionLimitrevert due to underflow . . . . . . . . . . . . . .9 7.1.5OUSGInstantManagerredemptions will be bricked if BlackRock deploys a newBUIDLRe- deemercontract and sunsets the existing one . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 7.1.6ROUSG::unwrapcan unnecessarily return slightly lessOUSGtokens than users originally wrapped . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 7.1.7 Protocol may be short-changed byBuidlRedeemerduring a USDC depeg event . . . . . . . 12 7.2 Informational . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 7.2.1 Consider implementing unlimited approvals forrOUSGtoken . . . . . . . . . . . . . . . . . . . 14 7.2.2 Reduce approval before transferring tokens inrOUSG::transferFrom. . . . . . . . . . . . . 14 7.2.3 Transfer tokens before minting shares inrOUSG::wrap. . . . . . . . . . . . . . . . . . . . . . 14 7.2.4 Round up fees inOUSGInstantManager::\_getInstantMintFeesand\_getInstantRedemp- tionFeesto favor the protocol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 7.2.5 Misleading events are emitted when transferring a dust amount of rOUSG shares . . . . . . . 14 7.2.6 Consider allowingROUSG::burnto burn dust amounts . . . . . . . . . . . . . . . . . . . . . . 15 7.2.7\_assertUSDCPricebreaks the solidity style guide . . . . . . . . . . . . . . . . . . . . . . . . . 15 7.3 Gas Optimization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 7.3.1 Cache array length outside of loops and consider unchecked loop incrementing . . . . . . . . 16 7.3.2 Cache storage variables in stack when read multiple times without being changed . . . . . . 16 7.3.3 Avoid unnecessary initialization to zero . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 7.3.4InvestorBasedRateLimiter::\_initializeInvestorStateshould return newly createdin- vestorIdto save re-reading it from storage . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 7.3.5 RefactorInvestorBasedRateLimiter::checkAndUpdateMintLimitandcheckAndUp- dateRedemptionLimitto avoid performing unnecessary operations when creating a new investor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 7.3.6 InInvestorBasedRateLimiter::\_setAddressToInvestorIdfirst readaddressToIn- vestorId\[investorAddress\]then use it in theifstatement check . . . . . . . . . . . . . . 18 7.3.7 InInvestorBasedRateLimiter::\_setAddressToInvestorIdusedeletewhen setting to zero for gas refund . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 7.3.8 Remove return parameters fromrOUSG::\_mintSharesand\_burnSharesas they are never read . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 7.3.9 InOUSGInstantManager::\_mintand\_redeemcachefeeReceiverand only emit fee event if fees are deducted . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 7.3.10 ChangeROUSG::unwrapto return amount ofOUSGoutput tokens then use that as input when calling\_redeeminOUSGInstantManager::redeemRebasingOUSG. . . . . . . . . . . . . . . . 20 1 1 About Cyfrin Cyfrin is a Web3 security company dedicated to bringing industry-leading protection and education to our partners and their projects. Our goal is to create a safe, reliable, and transparent environment for everyone in Web3 and DeFi. Learn more about us at cyfrin.io. 2 Disclaimer The Cyfrin team makes every effort to find as many vulnerabilities in the code as possible in the given time but holds no responsibility for the findings in this document. A security audit by the team does not endorse the underlying business or product. The audit was time-boxed and the review of the code was solely on the security aspects of the solidity implementation of the contracts. 3 Risk Classification Impact: HighImpact: MediumImpact: Low Likelihood: HighCriticalHighMedium Likelihood: MediumHighMediumLow Likelihood: LowMediumLowLow 4 Protocol Summary Ondo Finance is a Real-World Asset Tokenization protocol which aims to bring institutional-grade investment prod- ucts onto blockchains. This audit only concerned: •OUSGa tokenized wrapper of the Blackrock short-term US Treasuries ETF •rOUSGa rebalancing wrapper forOUSG •OUSGInstantManagera manager contract that allows users to mint and redeemOUSGandrOUSG • a couple of rate-limiting contracts General Overview: Users who have satisfied KYC and other applicable regulatory requirements are able to useOUSGInstantManager to: • mintOUSG/rOUSGin exchange forUSDC • redeemOUSG/rOUSGto receiveUSDC OUSGandrOUSGfunction asERC20tokens which users can transfer only to other KYC’d users and the protocol admin can place time-based global/individual user limits on the amount of allowed mints and redemptions. TheUSDprice ofOUSGis set every day by an off-chain Oracle controlled by the protocol and the price is expected to be "up only" to reflect the yield generated by the underlying real-world assets. External Integrations: The protocol’s primary external integration is with Blackrock’s newBUIDLtoken and associated redemption con- tract. When users redeemOUSG/rOUSGviaOUSGInstantManagerthe protocol must provide them withUSDC. In order to source thisUSDCthe protocol redeems enoughBUIDLfrom Blackrock’s redemption contract to cover the required USDCas Blackrock’s redemption contract provides 1:1BUIDL:USDCredemptions. 2 There is no on-chain mechanism for the protocol to depositBUIDLwith Blackrock; this process happens off-chain and we are to assume there will always be sufficientBUIDLto redeem such that the protocol will always be able to provideUSDCwhen users redeemOUSG/rOUSG. Centralization Risks: Due to the regulated nature of the underlying assets being tokenized and applicable regulatory requirements, the protocol is highly centralized by design including the ability for the protocol admins to seize the assets of users; users must place a high degree of trust in the protocol team. All issues related to centralization were outside the scope of the audit. 5 Audit Scope The following contracts were included in the scope for this audit: contracts/ousg/ousgInstantManager.sol contracts/ousg/rOUSG.sol contracts/ousg/InvestorBasedRateLimiter.sol contracts/InstantMintTimeBasedRateLimiter.sol contracts/kyc/KYCRegistryClientUpgradeable.sol 6 Executive Summary Over the course of 9 days, the Cyfrin team conducted an audit on the Ondo Finance smart contracts provided by Ondo Finance. In this period, a total of 24 issues were found. The protocol was recently audited in an audit contest and we were auditing a version of the codebase which had resolved the most important findings from that contest with knowledge of the contest findings. There was 1 new contractInvestorBasedRateLimiter.solwhich was not present in the audit contest. Our findings consisted of 7 Low severity issues with the remainder being informational and gas optimizations. Of the 7 Low severity issues: • 2 related to unlikely scenarios that could arise in the integration with Blackrock’sBUIDLredemption contract • 2 related to breaking aInvestorBasedRateLimiterinvariant: "when a newinvestorIdis created, it should be associated with one or more valid addresses" • 1 related to breaking aROUSGinvariant: "when unwrapping users should receive the same amount ofOUSG input tokens they provided when they wrapped, irrespective of price" • 2 related to underflow reverts inside checks performed byInvestorBasedRateLimiterandInstantMint- TimeBasedRateLimiter All of the above findings were successfully mitigated by the protocol team. Fuzz Testing: As part of our audit we used both stateless and stateful/invariant fuzz testing; all code for our fuzz testing was delivered to the protocol team as an additional deliverable at the conclusion of the audit. 3 Summary Project NameOndo Finance Repositoryrwa-internal Commit6747ebada1c8. . . Audit TimelineApr 8th - Apr 18th MethodsManual Review, Stateful Fuzzing Issues Found Critical Risk0 High Risk0 Medium Risk0 Low Risk7 Informational7 Gas Optimizations10 Total Issues24 Summary of Findings \[L-1\]InvestorBasedRateLimiter::setInvestorMintLimitandset- InvestorRedemptionLimitcan make subsequent calls tocheckAndUpdateM- intLimitandcheckAndUpdateRedemptionLimitrevert due to underflow Resolved \[L-2\] Prevent creating an investor record associated with the zero addressResolved \[L-3\] Prevent creating an investor record associated with no addressResolved \[L-4\]InstantMintTimeBasedRateLimiter::\_setInstantMintLimitand\_- setInstantRedemptionLimitcan make subsequent calls to\_checkAndUp- dateInstantMintLimitand\_checkAndUpdateInstantRedemptionLimitre- vert due to underflow Resolved \[L-5\]OUSGInstantManagerredemptions will be bricked if BlackRock deploys a newBUIDLRedeemercontract and sunsets the existing one Resolved \[L-6\]ROUSG::unwrapcan unnecessarily return slightly lessOUSGtokens than users originally wrapped Resolved \[L-7\] Protocol may be short-changed byBuidlRedeemerduring a USDC depeg event Resolved \[I-1\] Consider implementing unlimited approvals forrOUSGtokenAcknowledged \[I-2\] Reduce approval before transferring tokens inrOUSG::transferFromAcknowledged \[I-3\] Transfer tokens before minting shares inrOUSG::wrapAcknowledged \[I-4\] Round up fees inOUSGInstantManager::\_getInstantMintFeesand\_- getInstantRedemptionFeesto favor the protocol Acknowledged 4 \[I-5\] Misleading events are emitted when transferring a dust amount of rOUSG shares Acknowledged \[I-6\] Consider allowingROUSG::burnto burn dust amountsResolved \[I-7\]\_assertUSDCPricebreaks the solidity style guideResolved \[G-1\] Cache array length outside of loops and consider unchecked loop incre- menting Acknowledged \[G-2\] Cache storage variables in stack when read multiple times without being changed Acknowledged \[G-3\] Avoid unnecessary initialization to zeroResolved \[G-4\]InvestorBasedRateLimiter::\_initializeInvestorStateshould re- turn newly createdinvestorIdto save re-reading it from storage Resolved \[G-5\] RefactorInvestorBasedRateLimiter::checkAndUpdateMintLimitand checkAndUpdateRedemptionLimitto avoid performing unnecessary opera- tions when creating a new investor Acknowledged \[G-6\] InInvestorBasedRateLimiter::\_setAddressToInvestorIdfirst read addressToInvestorId\[investorAddress\]then use it in theifstatement check Acknowledged \[G-7\]InInvestorBasedRateLimiter::\_setAddressToInvestorIduse deletewhen setting to zero for gas refund Acknowledged \[G-8\] Remove return parameters fromrOUSG::\_mintSharesand\_burnShares as they are never read Resolved \[G-9\] InOUSGInstantManager::\_mintand\_redeemcachefeeReceiverand only emit fee event if fees are deducted Acknowledged \[G-10\] ChangeROUSG::unwrapto return amount ofOUSGoutput to- kens then use that as input when calling\_redeeminOUSGInstantMan- ager::redeemRebasingOUSG Acknowledged 5 7 Findings 7.1 Low Risk 7.1.1InvestorBasedRateLimiter::setInvestorMintLimitandsetInvestorRedemptionLimitcan make subsequent calls tocheckAndUpdateMintLimitandcheckAndUpdateRedemptionLimitrevert due to underflow Description:InvestorBasedRateLimiter::\_checkAndUpdateRateLimitStateL211-213 subtracts the current mint/redemption amount from the corresponding limit: if (amount > rateLimit.limit - rateLimit.currentAmount) { revert RateLimitExceeded(); } IfsetInvestorMintLimitorsetInvestorRedemptionLimitare used to set the limit amount for minting or redemp- tions smaller than the current mint/redemption amount, calls to this function will revert due to underflow. Impact:InvestorBasedRateLimiter::setInvestorMintLimitandsetInvestorRedemptionLimitcan make subsequent calls tocheckAndUpdateMintLimitandcheckAndUpdateRedemptionLimitrevert due to underflow. Proof of Concept:Add this drop-in PoC toforge-tests/ousg/InvestorBasedRateLimiter/setters.t.sol: function test\_setInvestorMintLimit\_underflow\_DoS() public initDefault(alice) { // first perform a mint uint256 mintAmount = rateLimiter.defaultMintLimit(); vm.prank(client); rateLimiter.checkAndUpdateMintLimit(alice, mintAmount); // admin now reduces the mint limit to be under the current // minted amount uint256 aliceInvestorId = 1; uint256 newMintLimit = mintAmount - 1; vm.prank(guardian); rateLimiter.setInvestorMintLimit(aliceInvestorId, newMintLimit); // subsequent calls to\`checkAndUpdateMintLimit\`revert due to underflow vm.prank(client); rateLimiter.checkAndUpdateMintLimit(alice, 1); // same issue affects\`setInvestorRedemptionLimit\` } Run with:forge test --match-test test\_setInvestorMintLimit\_underflow\_DoS Produces output: Ran 1 test for forge-tests/ousg/InvestorBasedRateLimiter/setters.t.sol:Test\_InvestorBasedRateLimiter\_setters\_ETH,! \[FAIL. Reason: panic: arithmetic underflow or overflow (0x11)\] test\_setInvestorMintLimit\_underflow\_DoS() (gas: 264384),! Suite result: FAILED. 0 passed; 1 failed; 0 skipped; finished in 1.09ms (116.74μs CPU time) Recommended Mitigation:Explicitly handle the case where the limit is smaller than the current mint/redemption amount: if (rateLimit.limit <= rateLimit.currentAmount || amount > rateLimit.limit - rateLimit.currentAmount) { revert RateLimitExceeded(); 6 } Ondo:Fixed in commit fb8ecff. Cyfrin:Verified. 7.1.2 Prevent creating an investor record associated with the zero address Description:InvestorBasedRateLimiter::checkAndUpdateMintLimitandcheckAndUpdateRedemptionLimit can create a new investor record and associate it with the zero address. Impact:Investor records can be created which are associated with the zero address. This breaks the following invariant of theInvestorBasedRateLimitercontract: when a newinvestorIdis created, it should be associated with one or more valid addresses Proof of Concept:Add this drop-in PoC toforge-tests/ousg/InvestorBasedRateLimiter/client.t.sol: function test\_mint\_zero\_address() public { uint256 mintAmount = rateLimiter.defaultMintLimit(); vm.prank(client); rateLimiter.checkAndUpdateMintLimit(address(0), mintAmount); // an investor has been created with a 0 address assertEq(1, rateLimiter.addressToInvestorId(address(0))); // same issue affects checkAndUpdateRedemptionLimit } Run with:forge test --match-test test\_mint\_zero\_address Recommended Mitigation:In\_setAddressToInvestorIdrevert for the zero address: function \_setAddressToInvestorId( address investorAddress, uint256 newInvestorId ) internal { if(investorAddress == address(0)) revert NoZeroAddress(); Ondo:Fixed in commit bac99d0. Cyfrin:Verified. 7.1.3 Prevent creating an investor record associated with no address Description:InvestorBasedRateLimiter::initializeInvestorStateDefaultis supposed to associate a newly created investor with one or more addresses but theforloop which does this can be bypassed by calling the function with an empty array: function initializeInvestorStateDefault( address\[\] memory addresses ) external onlyRole(CONFIGURER\_ROLE) { \_initializeInvestorState( addresses, defaultMintLimit, defaultRedemptionLimit, defaultMintLimitDuration, defaultRedemptionLimitDuration ); } 7 function \_initializeInvestorState( address\[\] memory addresses, uint256 mintLimit, uint256 redemptionLimit, uint256 mintLimitDuration, uint256 redemptionLimitDuration ) internal { uint256 investorId = ++investorIdCounter; // @audit this\`for\`loop can by bypassed by calling //\`initializeInvestorStateDefault\`with an empty array for (uint256 i = 0; i < addresses.length; ++i) { // Safety check to ensure the address is not already associated with an investor // before associating it with a new investor if (addressToInvestorId\[addresses\[i\]\] != 0) { revert AddressAlreadyAssociated(); } \_setAddressToInvestorId(addresses\[i\], investorId); } investorIdToMintState\[investorId\] = RateLimit({ currentAmount: 0, limit: mintLimit, lastResetTime: block.timestamp, limitDuration: mintLimitDuration }); investorIdToRedemptionState\[investorId\] = RateLimit({ currentAmount: 0, limit: redemptionLimit, lastResetTime: block.timestamp, limitDuration: redemptionLimitDuration }); } Impact:An investor record can be created without any associated address. This breaks the following invariant of theInvestorBasedRateLimitercontract: when a newinvestorIdis created, it should be associated with one or more valid addresses Proof of Concept:Add this drop-in PoC toforge-tests/ousg/InvestorBasedRateLimiter/setters.t.sol: function test\_initializeInvestor\_NoAddress() public { // no investor created assertEq(0, rateLimiter.investorIdCounter()); // empty input array will bypass the\`for\`loop that is supposed // to associate addresses to the newly created investor address\[\] memory addresses; vm.prank(guardian); rateLimiter.initializeInvestorStateDefault(addresses); // one investor created assertEq(1, rateLimiter.investorIdCounter()); // not associated with any addresses assertEq(0, rateLimiter.investorAddressCount(1)); } 8 Run with:forge test --match-test test\_initializeInvestor\_NoAddress Recommended Mitigation:In\_initializeInvestorStaterevert if the input address array is empty: uint256 addressesLength = addresses.length; if(addressesLength == 0) revert EmptyAddressArray(); Ondo:Fixed in commit bac99d0. Cyfrin:Verified. 7.1.4InstantMintTimeBasedRateLimiter::\_setInstantMintLimitand\_setInstantRedemptionLimitcan make subsequent calls to\_checkAndUpdateInstantMintLimitand\_checkAndUpdateInstantRedemp- tionLimitrevert due to underflow Description:InstantMintTimeBasedRateLimiter::\_checkAndUpdateInstantMintLimitL103-106 subtracts the currently minted amount from the mint limit: require( amount <= instantMintLimit - currentInstantMintAmount, "RateLimit: Mint exceeds rate limit" ); If\_setInstantMintLimitis used to setinstantMintLimit < currentInstantMintAmount, subsequent calls to this function will revert due the underflow. The same is true for\_setInstantRedemptionLimitand\_checkAndUp- dateInstantRedemptionLimit. Impact:InstantMintTimeBasedRateLimiter::\_setInstantMintLimitand\_setInstantRedemptionLimitcan make subsequent calls to\_checkAndUpdateInstantMintLimitand\_checkAndUpdateInstantRedemptionLimit revert due to underflow. Recommended Mitigation:Explicitly handle the case where the limit is smaller than the current mint/redemption amount: function \_checkAndUpdateInstantMintLimit(uint256 amount) internal { require( instantMintLimit > currentInstantMintAmount && amount <= instantMintLimit - currentInstantMintAmount,,! "RateLimit: Mint exceeds rate limit" ); } function \_checkAndUpdateInstantRedemptionLimit(uint256 amount) internal { require( instantRedemptionLimit > currentInstantRedemptionAmount && amount <= instantRedemptionLimit - currentInstantRedemptionAmount,,! "RateLimit: Redemption exceeds rate limit" ); } Ondo:Fixed in commit fb8ecff. Cyfrin:Verified. 9 7.1.5OUSGInstantManagerredemptions will be bricked if BlackRock deploys a newBUIDLRedeemercontract and sunsets the existing one Description:TheBUIDLRedeemercontract is a very new contract; it is very possible that in the future a new version of the contract will be deployed and the current version will cease to function. To future-proofOUSGInstantManagerand ensure it will continue to function in this situation, remove theimmutable keyword from thebuidlRedeemerdefinition and add a setter function that allows it to be updated in the future. Ondo:If a newBUIDLRedeemercontract is deployed our plan is to deploy a newOUSGInstantManager. We prefer to make it harder for us to change the address ofbuidlRedeemerto ensure there is proper due diligence of any changes. 7.1.6ROUSG::unwrapcan unnecessarily return slightly lessOUSGtokens than users originally wrapped Description:One invariant of theROUSGtoken is: when unwrapping users should receive the same amount of OUSG input tokens they provided when they wrapped, irrespective of price However this can often not be the case asROUSG::unwrapcan unnecessarily return slightly lessOUSGtokens than users originally wrapped. Impact:Users will unnecessarily receive slightly less tokens than they originally wrapped, breaking an invariant of theROUSGcontract. Proof of Concept:Run this stand-alone stateless fuzz test which shows the problem: // SPDX-License-Identifier: MIT pragma solidity ^0.8.23; import "forge-std/Test.sol"; // run from base project directory with: // forge test --match-contract ROUSGWrapUnwrapBrokenInvariantTest -vvv contract ROUSGWrapUnwrapBrokenInvariantTest is Test { uint256 public constant OUSG\_TO\_ROUSG\_SHARES\_MULTIPLIER = 10\_000; function \_getROUSGByShares(uint256 \_shares, uint256 ousgPrice) internal pure returns (uint256 rOUSGAmount) {,! rOUSGAmount = (\_shares \* ousgPrice) / (1e18 \* OUSG\_TO\_ROUSG\_SHARES\_MULTIPLIER); } function getSharesByROUSG(uint256 \_rOUSGAmount, uint256 ousgPrice) internal pure returns (uint256 shares) { shares = (\_rOUSGAmount \* 1e18 \* OUSG\_TO\_ROUSG\_SHARES\_MULTIPLIER) / ousgPrice; } function \_wrap(uint256 \_OUSGAmount) internal pure returns (uint256 shares) { require(\_OUSGAmount > 0, "rOUSG: can't wrap zero OUSG tokens"); shares = \_OUSGAmount \* OUSG\_TO\_ROUSG\_SHARES\_MULTIPLIER; } function \_unwrap(uint256 \_rOUSGAmount, uint256 ousgPrice) internal pure returns(uint256 tokens) { require(\_rOUSGAmount > 0, "rOUSG: can't unwrap zero rOUSG tokens"); uint256 ousgSharesAmount = getSharesByROUSG(\_rOUSGAmount, ousgPrice); vm.assume(ousgSharesAmount >= OUSG\_TO\_ROUSG\_SHARES\_MULTIPLIER); 10 tokens = ousgSharesAmount / OUSG\_TO\_ROUSG\_SHARES\_MULTIPLIER; } function test\_WrapUnwrapReturnsInputTokens(uint256 initialOUSGAmount, uint256 ousgPrice) external { // bound inputs initialOUSGAmount = bound(initialOUSGAmount, 100000e18, type(uint128).max); ousgPrice = bound(ousgPrice, 105e18, 106e18); // wrap OUSG into rOUSG uint256 rousgShares = \_wrap(initialOUSGAmount); // get the token amount of rOUSG equivalent to the received shares uint256 rousgAmount = \_getROUSGByShares(rousgShares, ousgPrice); // use the token amount to unwrap rOUSG back into OUSG uint256 finalOUSGAmount = \_unwrap(rousgAmount, ousgPrice); // verify amounts match; this fails as user is slighty short-changed assertEq(initialOUSGAmount, finalOUSGAmount); } } RecommendedMitigation:WhencallingROUSG::unwrap,burnandOUSGInstantMan- ager::redeemRebasingOUSG, instead of passing in theROUSGtoken amount the callers should pass in the share amount which can be retrieved viaROUSG::sharesOf. The output token calculation can then be performed asshares / OUSG\_TO\_ROUSG\_SHARES\_MULTIPLIERwhich will always return the correct amount of tokens. The existing functions do not necessarily need to be removed but additional functions should be created to allow users to input the share amounts. The following function has been tested via an invariant fuzz testing suite and appears to always return the correct amount: // @audit this function allow unwrapping by shares instead of tokens // to prevent users being slightly short-changed such that users will // always receive the same input amount of OUSG tokens function unwrapShares(uint256 \_shares) external whenNotPaused { uint256 ousgTokens = \_shares / OUSG\_TO\_ROUSG\_SHARES\_MULTIPLIER; require(ousgTokens > 0, "rOUSG: no tokens to send, unwrap more shares"); uint256 rousgBurned = getROUSGByShares(\_shares); \_burnShares(msg.sender, \_shares); ousg.transfer(msg.sender, ousgTokens); emit Transfer(msg.sender, address(0), rousgBurned); emit TransferShares(msg.sender, address(0), \_shares); } Proof that this mitigation works, using a modified version of the PoC stateless fuzz test: First ensure thatfoundry.tomlhas the fuzz setting increased for example: \[fuzz\] runs = 1000000 Then run this stand-alone stateless fuzz test which verifies the solution: // SPDX-License-Identifier: MIT 11 pragma solidity ^0.8.23; import "forge-std/Test.sol"; // run from base project directory with: // forge test --match-contract ROUSGWrapUnwrapFixedInvariantTest -vvv contract ROUSGWrapUnwrapFixedInvariantTest is Test { uint256 public constant OUSG\_TO\_ROUSG\_SHARES\_MULTIPLIER = 10\_000; function \_wrap(uint256 \_OUSGAmount) internal pure returns (uint256 shares) { require(\_OUSGAmount > 0, "rOUSG: can't wrap zero OUSG tokens"); shares = \_OUSGAmount \* OUSG\_TO\_ROUSG\_SHARES\_MULTIPLIER; } function \_unwrapShares(uint256 shares) internal pure returns(uint256 tokens) { tokens = shares / OUSG\_TO\_ROUSG\_SHARES\_MULTIPLIER; } function test\_WrapUnwrapReturnsInputTokens(uint256 initialOUSGAmount, uint256 ousgPrice) external { // bound inputs initialOUSGAmount = bound(initialOUSGAmount, 100000e18, type(uint128).max); ousgPrice = bound(ousgPrice, 105e18, 106e18); // wrap OUSG into rOUSG uint256 rousgShares = \_wrap(initialOUSGAmount); // use the token amount to unwrap rOUSG back into OUSG uint256 finalOUSGAmount = \_unwrapShares(rousgShares); assertEq(initialOUSGAmount, finalOUSGAmount); } } Ondo:Fixed in commits df0e491, 2aa437a. We decided on not making any changes toOUSGInstantManagerdue to the amount of code changes necessary. Cyfrin:Verified. 7.1.7 Protocol may be short-changed byBuidlRedeemerduring a USDC depeg event Description:OUSGInstantManager::\_redeemBUIDLassumes that 1 BUIDL = 1 USDC as it enforces receiving 1 USDC for every 1 BUIDL it redeems: uint256 usdcBalanceBefore = usdc.balanceOf(address(this)); buidl.approve(address(buidlRedeemer), buidlAmountToRedeem); buidlRedeemer.redeem(buidlAmountToRedeem); require( usdc.balanceOf(address(this)) == usdcBalanceBefore + buidlAmountToRedeem, "OUSGInstantManager::\_redeemBUIDL: BUIDL:USDC not 1:1" ); In the event of a USDC depeg (especially if the depeg is sustained),BUIDLRedeemershould return greater than a 1:1 ratio since 1 USDC would not be worth $1, hence 1 BUIDL != 1 USDC meaning the value of the protocol’s BUIDL is worth more USDC. HoweverBUIDLReceiverdoes not do this, it only ever returns 1:1. Impact:In the event of a USDC depeg the protocol will be short-changed byBuidlRedeemersince it will happily 12 receive only 1 USDC for every 1 BUIDL redeemed, even though the value of 1 BUIDL would be greater than the value of 1 USDC due to the USDC depeg. Recommended Mitigation:To prevent this situation the protocol would need to use an oracle to check whether USDC had depegged and if so, calculate the amount of USDC it should receive in exchange for its BUIDL. If it is short-changed it would either have to revert preventing redemptions or allow the redemption while saving the short-changed amount to storage then implement an off-chain process with BlackRock to receive the short- changed amount. Alternatively the protocol may simply accept this as a risk to the protocol that it will be willingly short-changed during a USDC depeg in order to allow redemptions to continue. Ondo:Fixed in commits 408bff1, 8a9cae9. We now use Chainlink USDC/USD Oracle and if USDC depegs below our tolerated minimum value both minting and redemptions will be stopped. Cyfrin:Verified. 13 7.2 Informational 7.2.1 Consider implementing unlimited approvals forrOUSGtoken Description:ERC20 tokens commonly implement unlimited approvals by allowing users to approve spenders for type(uint256).max. Consider implementing this common feature; an example from OpenZeppelin. Ondo:Acknowledged. 7.2.2 Reduce approval before transferring tokens inrOUSG::transferFrom Description:rOUSG::transferFromL286-289 currently checks approvals, transfers the tokens then reduces the approvals: // verify approval require(currentAllowance >= \_amount, "TRANSFER\_AMOUNT\_EXCEEDS\_ALLOWANCE"); // perform transfer \_transfer(\_sender, \_recipient, \_amount); // reduce approval \_approve(\_sender, msg.sender, currentAllowance - \_amount); A safer coding pattern is to reduce the approval first then transfer tokens similar to OpenZeppelin’s impementation. Ondo:Acknowledged. 7.2.3 Transfer tokens before minting shares inrOUSG::wrap Description:rOUSG::wrapL411-413 currently mints shares before transferring tokens used to mint those shares: // mint shares uint256 ousgSharesAmount = \_OUSGAmount \* OUSG\_TO\_ROUSG\_SHARES\_MULTIPLIER; \_mintShares(msg.sender, ousgSharesAmount); // transfer tokens used to mint the shares ousg.transferFrom(msg.sender, address(this), \_OUSGAmount); A safer coding pattern is to transfer the tokens first then mint the shares. Ondo:Acknowledged. 7.2.4 Round up fees inOUSGInstantManager::\_getInstantMintFeesand\_getInstantRedemptionFeesto fa- vor the protocol Description:Solidity rounds down by default so consider explicitly rounding up fees inOUSGInstantManager::\_- getInstantMintFeesand\_getInstantRedemptionFeesto favor the protocol. Ondo:Acknowledged. 7.2.5 Misleading events are emitted when transferring a dust amount of rOUSG shares Description:CallingROUSG.transferSharesemits two events: TransferShares: How much rOUSG shares were transferredTransfer: How much rOUSG tokens were trans- ferred Calling this function with a dust amount will emit an event that a non-zero amount of shares was transferred, together with an event that zero tokens were transferred as thegetROUSGByShareswill round to 0. Ondo:Acknowledged. 14 7.2.6 Consider allowingROUSG::burnto burn dust amounts Description:ROUSG::burnis used by admins to burnrOUSGtokens from any account for regulatory reasons. It does not allow burning a share amount smaller than 1e4, because this is less than a wei ofOUSG. if (ousgSharesAmount < OUSG\_TO\_ROUSG\_SHARES\_MULTIPLIER) revert UnwrapTooSmall(); Depending on the current and future regulatory situation it could be necessary to always be able to burn all shares from users. Recommended Mitigation:Consider allowing theburnfunction to burn all remaining shares even if under the minimum amount. Ondo:Fixed in commit 2aa437a. Cyfrin:Verified. 7.2.7\_assertUSDCPricebreaks the solidity style guide Description:The\_assertUSDCPricefunction is public and starts with an underscore. According to the solidity style guide, this convention is suggested for non-external functions and state variables (private or internal). Recommended Mitigation:Remove the\_, or change the visibility of the function. Ondo:Fixed in commit fc1c8fb. Cyfrin:Verified. 15 7.3 Gas Optimization 7.3.1 Cache array length outside of loops and consider unchecked loop incrementing Description:Cache array length outside of loops and consider usingunchecked {++i;}if not compiling withsolc --ir-optimized --optimize: File: contracts/ousg/InvestorBasedRateLimiter.sol 253: for (uint256 i = 0; i < addresses.length; ++i) { File: contracts/ousg/ousgInstantManager.sol 881: for (uint256 i = 0; i < exCallData.length; ++i) { Ondo:Acknowledged. 7.3.2 Cache storage variables in stack when read multiple times without being changed Description:Reading from storage is considerably more expensive than reading from the stack so cache storage variables when read multiple times without being changed: File: contracts/ousg/InvestorBasedRateLimiter.sol // @audit cache these then use cache values when emitting event to save 2 storage reads 324: --investorAddressCount\[previousInvestorId\]; 335: ++investorAddressCount\[newInvestorId\]; // @audit cache and use cached value for check in L470 to save 1 storage read 462: if (mintState.lastResetTime == 0) { // @audit cache and use cached value for check in L506 to save 1 storage read 498: if (redemptionState.lastResetTime == 0) { Ondo:Acknowledged. 7.3.3 Avoid unnecessary initialization to zero Description:Avoid unnecessary initialization to zero: File: contracts/ousg/InvestorBasedRateLimiter.sol 253: for (uint256 i = 0; i < addresses.length; ++i) { File: contracts/ousg/ousgInstantManager.sol 106: uint256 public mintFee = 0; 109: uint256 public redeemFee = 0; 881: for (uint256 i = 0; i < exCallData.length; ++i) { Ondo:Fixed in commit a7dab64. Cyfrin:Verified. 16 7.3.4InvestorBasedRateLimiter::\_initializeInvestorStateshould return newly createdinvestorIdto save re-reading it from storage Description:InvestorBasedRateLimiter::\_initializeInvestorStateshould return the newly createdin- vestorId; this can then be used insidecheckAndUpdateMintLimitandcheckAndUpdateRedemptionLimitto save 1 storage read in each function. For example takecheckAndUpdateMintLimit: \_initializeInvestorState( addresses, defaultMintLimit, defaultRedemptionLimit, defaultMintLimitDuration, defaultRedemptionLimitDuration ); // @audit GAS - save 1 storage read by having \_initializeInvestorState // return the new\`investorId\` investorId = addressToInvestorId\[investorAddress\]; This can simply become: investorId = \_initializeInvestorState( addresses, defaultMintLimit, defaultRedemptionLimit, defaultMintLimitDuration, defaultRedemptionLimitDuration ); Ondo:Fixed in commit 192c7ca. Cyfrin:Verified. 7.3.5 RefactorInvestorBasedRateLimiter::checkAndUpdateMintLimitandcheckAndUpdateRedemption- Limitto avoid performing unnecessary operations when creating a new investor Description:When creating a new investor insideInvestorBasedRateLimiter::checkAndUpdateMintLimitand checkAndUpdateRedemptionLimitthere is no need to do a lot of the current processing that occurs after the secondifstatement. A more optimized version could look like this: function checkAndUpdateMintLimitOptimized( address investorAddress, uint256 mintAmount ) external override onlyRole(CLIENT\_ROLE) { if (mintAmount == 0) { revert InvalidAmount(); } uint256 investorId = addressToInvestorId\[investorAddress\]; if (investorId == 0) { // @audit GAS - for new investor, revert if\`mintAmount > defaultMintLimit\` // otherwise execute next code then update investorIdToMintState\[investorId\].currentAmount // and slightly change emitted event since prevAmount = 0 uint256 defaultMintLimitCache = defaultMintLimit; if(mintAmount > defaultMintLimitCache) revert RateLimitExceeded(); // If this is a new investor, initialize their state with the default values 17 address\[\] memory addresses = new address\[\](1); addresses\[0\] = investorAddress; // @audit GAS - return new investorId from\`\_initializeInvestorState\` investorId = \_initializeInvestorState( addresses, defaultMintLimit, defaultRedemptionLimit, defaultMintLimitDuration, defaultRedemptionLimitDuration ); // @audit now update current minted amount investorIdToMintState\[investorId\].currentAmount = mintAmount; // @audit and alter emitted event to reflect first mint for this new investor emit MintStateUpdated( investorAddress, investorId, 0, mintAmount, defaultMintLimitCache - mintAmount ); } else { // @audit GAS - wrap remaining code in an\`else\`to only // execute if it wasn't a new investor RateLimit storage mintState = investorIdToMintState\[investorId\]; uint256 prevAmount = mintState.currentAmount; \_checkAndUpdateRateLimitState(mintState, mintAmount); emit MintStateUpdated( investorAddress, investorId, prevAmount, mintState.currentAmount, mintState.limit - mintState.currentAmount ); } } The same optimization could be applied tocheckAndUpdateRedemptionLimit. Ondo:Acknowledged. 7.3.6 InInvestorBasedRateLimiter::\_setAddressToInvestorIdfirstreadaddressToIn- vestorId\[investorAddress\]then use it in theifstatement check Description:InInvestorBasedRateLimiter::\_setAddressToInvestorIdfirstreadaddressToIn- vestorId\[investorAddress\]then use it in theifstatement check to save 1 storage read: function \_setAddressToInvestorId( address investorAddress, uint256 newInvestorId ) internal { // @audit GAS - do this first then use it in\`if\`check to save 1 storage read uint256 previousInvestorId = addressToInvestorId\[investorAddress\]; // prevents creating the same existing association 18 if (previousInvestorId == newInvestorId) { revert AddressAlreadyAssociated(); } Ondo:Acknowledged. 7.3.7 InInvestorBasedRateLimiter::\_setAddressToInvestorIdusedeletewhen setting to zero for gas refund Description:InInvestorBasedRateLimiter::\_setAddressToInvestorIdusedeletewhen setting to zero: // If the address is not being disassociated from all investors, increment the count // for the investor the address is being associated with. if (newInvestorId != 0) { ++investorAddressCount\[newInvestorId\]; emit AddressToInvestorIdSet( investorAddress, newInvestorId, investorAddressCount\[newInvestorId\] ); // @audit move this here when setting a valid value addressToInvestorId\[investorAddress\] = newInvestorId; } else { // @audit use\`delete\`when setting to 0 for gas refund delete addressToInvestorId\[investorAddress\]; } Ondo:Acknowledged. 7.3.8 Remove return parameters fromrOUSG::\_mintSharesand\_burnSharesas they are never read Description:Remove return parameters fromrOUSG::\_mintSharesand\_burnSharesas they are never read. This saves 1 storage read in each function plus the cost of the return parameters. Ondo:Fixed in commit dc91728. Cyfrin:Verified. 7.3.9 InOUSGInstantManager::\_mintand\_redeemcachefeeReceiverand only emit fee event if fees are deducted Description:InOUSGInstantManager::\_mintcachefeeReceiverand only emit fee event if fees are deducted to save 1 storage read: // Transfer USDC if (usdcFees > 0) { // @audit GAS - cache\`feeReceiver\`and only emit fee event if // fees are deducted address feeReceiverCached = feeReceiver; usdc.transferFrom(msg.sender, feeReceiverCached, usdcFees); emit MintFeesDeducted(msg.sender, feeReceiverCached, usdcFees, usdcAmountIn); } 19 A similar optimization can be made in\_redeem. Ondo:Acknowledged. 7.3.10 ChangeROUSG::unwrapto return amount ofOUSGoutput tokens then use that as input when calling \_redeeminOUSGInstantManager::redeemRebasingOUSG Description:ChangeROUSG::unwrapto return amount ofOUSGoutput tokens then use that as input when calling \_redeeminOUSGInstantManager::redeemRebasingOUSG: uint256 ousgAmountIn = rousg.unwrap(rousgAmountIn); usdcAmountOut = \_redeem(ousgAmountIn); Ondo:Acknowledged. 20
---
# Unknown
Security Review Report NM-0081 Ondo Finance (April 6, 2023) NM-0081 ONDO FINANCE - SECURITY REVIEW Contents 1 Executive Summary2 2 Audited Files3 3 Summary of Issues3 4 System Overview4 5 Risk Rating Methodology6 6 Issues7 6.1 \[Medium\] Rounding issue when calculating absolute changes in basis points (BPS) . . . . . . . . . . . . . . . . . . . . . . . .7 6.2 \[Low\] Changing oracle type does not remove previous oracle data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7 6.3 \[Low\] Lack of a two-step process for transferring ownership . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8 6.4 \[Low\] Use AccessControlDefaultAdminRules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8 6.5 \[Low\]\_setFTokenToChainlinkOracle(...)does not check oracle decimals . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8 6.6 \[Info\] Events in RWA oracles differ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9 6.7 \[Info\] Inconsistent behavior onprice == 0. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9 6.8 \[Info\] Incorrect check for decimals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 6.9 \[Info\] No check for fToken validity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 6.10 \[Best Practice\] Use of magic numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 6.11 \[Best Practice\]renounceOwnership(...)function should be disabled . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 7 Documentation Evaluation11 8 Test Suite Evaluation12 8.1 Contracts Compilation Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 8.2 Tests Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 8.3 Code Coverage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 8.4 Slither . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 9 About Nethermind15 1 NM-0081 ONDO FINANCE - SECURITY REVIEW 1 Executive Summary This document outlines the security review conducted by Nethermind for the Ondo Finance. The audit primarily focuses on oracles’ pricing assets on the Flux and CASH protocols.Flux Financeis a decentralized lending protocol developed by the Ondo Finance team that supports both permissionless and permissioned tokens. Assets on Flux are represented asfTokens. TheCASHprotocol, on the other hand, enables whitelisted users to gain exposure to RWAs through Cash tokens. The protocol employs Know Your Customer (KYC) procedures to allow users to mint Cash tokens. The audited code consists of451 lines of Solidity. The Ondo Finance team provided extensive documentation in the audit repository. The audit was performed using(a) manual analysis of the codebase, (b) automated analysis tools, (c) simulation of the smart contracts, and (d) creation of test cases.Along this document, we report11 points of attention, where one is classified asMedium, four are classified asLow, four are classified asInformationaland two are classified asBest Practice. The issues are summarized in Fig. 1. This document is organized as follows.Section 2 presents the files in the scope of this audit. Section 3 summarizes the issues. Section 4 presents the system overview. Section 5 discusses the risk rating methodology adopted for this audit. Section 6 details the issues. Section 7 discusses the documentation provided by the client for this audit. Section 8 presents the compilation, tests, and automated tests. Section 9 concludes the document. Medium Low Info Best Practices Best Practices 18.2% Info 36.4% Medium 9.1% Low 36.4% Severity (a) Acknowledged 36.4% Fixed 63.6% Status (b) Fig. 1: Distribution of issues: Critical(0),High(0),Medium(1),Low(4),Undetermined(0),Informational(4),Best Practices(2). Distribution of status: Fixed(7),Acknowledged(4),Mitigated(0),Unresolved(0) Summary of the Audit Audit TypeSecurity Review Initial ReportApr. 19, 2023 Response from ClientApr. 21, 2023 Final ReportApr. 24, 2023 MethodsManual Review, Automated Analysis RepositoryOndo Commit Hash (Initial Audit)6face44a82b7300be928cba30cd970636a77d93a DocumentationREADME.md Documentation AssessmentMedium Test Suite AssessmentHigh 2 NM-0081 ONDO FINANCE - SECURITY REVIEW 2 Audited Files ContractLoCCommentsRatioBlankTotal 1contracts/lending/fluxOracles/FluxOracle.sol19013872.6%31359 2contracts/lending/rwaOracles/RWAOracleRateCheck.sol5260115.4%19131 3contracts/lending/rwaOracles/RWAOracleExternalComparisonCheck.sol1359167.4%30256 4contracts/lending/fTokenOracle/fTokenOracle.sol745777.0%17148 Total45134676.7%97894 3 Summary of Issues FindingSeverityUpdate 1Rounding issue when calculating absolute changes in basis points (BPS)MediumAcknowledged 2Changing oracle type does not remove previous oracle dataLowFixed 3Lack of a two-step process for transferring ownershipLowFixed 4Use AccessControlDefaultAdminRulesLowAcknowledged 5\_setFTokenToChainlinkOracle(...)does not check oracle decimalsLowAcknowledged 6Events in RWA oracles differInfoFixed 7Inconsistent behavior onprice == 0InfoFixed 8Incorrect check for decimalsInfoFixed 9No check for fToken validityInfoFixed 10Use of magic numbersBest PracticesFixed 11renounceOwnership(...)function should be disabledBest PracticesAcknowledged 3 NM-0081 ONDO FINANCE - SECURITY REVIEW 4 System Overview The audit is based on four contracts: a)FluxOracle; b)RWAOracleRateCheck; c)RWAOracleExternalComparisonCheck; and, d)fTokenOracle. Fig.1 illustrates a structural diagram of the contracts and their association. FluxOracle IFluxOracle AccessControlEnumerable getUnderlyingPrice setFTokenToOracleType setHardcodedPrice setFTokenToRWAOracle setFTokenToChainlinkOracle onlyRole onlyRole onlyRole onlyRole RWAOracleRateCheck IRWAOracle AccessControlEnumerable getPriceData setPriceonlyRole RWAOracleExternalComparisonCheck IRWAOracleExternalComparisonCheck AccessControlEnumerable getPriceData setPriceonlyRole FTokenOracle IFTokenOracle Ownable getLatestPrice getPrice setMaxOracleTimeDelayonlyOwner Figure 1: Structural Diagram of Ondo Oracles TheFluxOraclecontract functions as a price oracle for the lending market, and it supports three distinct oracle types:Hardcoded, Tokenized\_RWA, andChainlink. TheDEFAULT\_ADMIN\_ROLEis the only role that can set an asset’s oracle type, and each oracle type has a specific role for updating its parameters. When retrieving the price of aTokenized\_RWAasset, the contract makes an external call to an oracle that implements theIRWAOracleinterface. For assets withChainlinkoracle type, the contract makes an external call to aChainlink price feed, which returns the asset’s price in USD with the price expressed in 36 decimals of the underlying asset. The contract uses the structChainlinkOracleInfo: 1structChainlinkOracleInfo { 2AggregatorV3Interface oracle; 3uint256scaleFactor; 4uint256maxChainlinkOracleTimeDelay; 5} The contract features several public functions −getUnderlyingPrice(...)is used to retrieve the price based on the associatedOracleType −setFTokenToOracleType(...)is used to set the oracle type for the providedfToken −setHardcodedPrice(...)is used to set the price of anfTokencontract’s underlying asset −setFTokenToRWAOracle(...)is used to associate a customfTokenwith an externalcToken −setFTokenToChainlinkOracle(...)is used to associate a customfTokenwith a Chainlink oracle TheRWAOracleRateCheckcontract implements theIRWAOracleinterface to determine the price of RWAs, such as CASH tokens. It employs a trusted off-chain party to set the price of a token within a specifiedMAX\_CHANGE\_DIFF\_BPSlimit of 100 basis points or 1%. In other words, the contract ensures a secure pricing mechanism for RWAs, which are critical assets on the Flux platform, by permitting a trusted source to determine their value within a predetermined range. The contract features two public functions: −getPriceData(...)is used to retrieve the most recently set RWA price data. −setPrice(...)is used bySETTER\_ROLEto set a new RWA price. It will verify that the previous price update was not done too recently and that the proposed price change does not exceed 1 4 NM-0081 ONDO FINANCE - SECURITY REVIEW TheRWAOracleExternalComparisonCheckcontract is designed to price RWAs through the implementation of theIRWAOracleinterface. This Oracle contract ensures the accuracy of RWA prices by cross-verifying them with aChainlinkprice feed and a trusted 3rd-party. In the case of OUSG, the price is verified with Chainlink’s SHV Oracle. The contract applies several checks before setting the price. These include verifying that the RWA price hasn’t been updated too recently, the difference between the old and new RWA price isn’t greater thanMAX\_ABSOLUTE\_DIFF\_BPS, the difference between the old and new Chainlink price isn’t greater thanMAX\_ABSOLUTE\_DIFF\_BPS + MAX\_- CHANGE\_DIFF\_BPS(otherwise the Chainlink price is flagged as malfunctioning), and the change in RWA price hasn’t deviated more than MAX\_CHANGE\_DIFF\_BPSfrom the change in the Chainlink price. Essentially, theRWAOracleExternalComparisonCheckprovides an additional layer of security by ensuring the accuracy of RWA prices through cross-checking them with a trusted third-party and aChainlinkprice feed. The contract features two public functions: −getPriceData(...)is used to retrieve the most recently set RWA price data. −setPrice(...)is used bySETTER\_ROLEto set a new RWA price. This function applies the same checks as those in theRWAOracleRateCheck and additionally incorporates a cross-check with a Chainlink price feed to confirm the accuracy of the RWA prices that are set by a trusted third-party. ThefTokenOraclecontract serves as an Oracle to determine the price of anfToken. This is achieved by using the exchange rate offTokento its underlying asset in the Flux lending market and multiplying it with the price feed of the underlying asset in USD from Chainlink. The resulting calculation produces the price of thefTokenin USD with 18 decimal places. ThefTokenOracleprovides valuable pricing information forfToken, which are tokens representing interest-bearing claims on underlying assets. The contract features several public functions −getLatestPrice(...)is utilized to retrieve a non-stale price offTokendenominated in the asset specified byunderlyingPriceFeed. This function acquires the price from the Chainlink price feed and applies additional checks to the returned price to confirm that it is not stale. −getPrice(...)is similar togetLatestPrice(...), but it does not include the additional checks. Therefore, the price returned by this function may be stale. −setMaxOracleTimeDelay(...)is used by the owner to set the maximum time delay for the Chainlink price feed. 5 NM-0081 ONDO FINANCE - SECURITY REVIEW 5 Risk Rating Methodology The risk rating methodology used by Nethermind follows the principles established by the OWASP Foundation. The severity of each finding is determined by two factors:LikelihoodandImpact. Likelihoodis a measure of how likely the finding is to be uncovered and exploited by an attacker. This factor will be one of the following values: a)High: The issue is trivial to exploit and has no specific conditions that need to be met; b)Medium: The issue is moderately complex and may have some conditions that need to be met; c)Low: The issue is very complex and requires very specific conditions to be met. When defining the likelihood of a finding other factors are also considered. These can include but are not limited to: Motive, opportunity, exploit accessibility, ease of discovery, and ease of exploit. Impactis a measure of the damage that may be caused if the finding were to be exploited by an attacker. This factor will be one of the following values: a)High: The issue can cause significant damage such as loss of funds or the protocol entering an unrecoverable state; b)Medium: The issue can cause moderate damage such as impacts that only affect a small group of users or only a particular part of the protocol; c)Low: The issue can cause little to no damage such as bugs that are easily recoverable or cause unexpected interactions that cause minor inconveniences. When defining the impact of a finding other factors are also considered. These can include but are not limited to Data/state integrity, loss of availability, financial loss, and reputation damage. After defining the likelihood and impact of an issue, the severity can be determined according to the table below. Severity Risk Impact HighMediumHighCritical MediumLowMediumHigh LowInfo/Best PracticesLowMedium UndeterminedUndeterminedUndeterminedUndetermined LowMediumHigh Likelihood To address issues that do not fit a High/Medium/Low severity, Nethermind also uses three more finding severities:Informational,Best Practices, andUndetermined. a)Informationalfindings do not pose any risk to the application, but they carry some information that the audit team intends to formally pass to the client; b)Best Practicefindings are used when some piece of code does not conform with smart contract development best practices; c)Undeterminedfindings are used when we cannot predict the impact or likelihood of the issue. 6 NM-0081 ONDO FINANCE - SECURITY REVIEW 6 Issues 6.1 \[Medium\] Rounding issue when calculating absolute changes in basis points (BPS) File(s):contracts/lending/rwaOracles/RWAOracleExternalComparisonCheck.sol,contracts/lending/rwaOracles/RWAOracleRateCheck.sol Description: In the RWA oracle, there is aMAX\_CHANGE\_DIFF\_BPSparameter that limits the change in the new price. This is done by calculating the difference between the new and old prices and dividing it by the old price. However, rounding down when calculating changeBpscould allow price change to be higher thanMAX\_CHANGE\_DIFF\_BPS. Example of an exploited scenario: 1. The admin setsMAX\_CHANGE\_DIFF\_BPS = 10; 2. If the old price ispreviousPrice = 10011and the new price isnewPrice = 10000, the calculation will be: 1change = newPrice - previousPrice = 10000 - 10011 = -11 2changeBps = (change \* BPS\_DENOMINATOR) / previousPrice = (-11 \* 10000) / 10011 = -10.99 3. Since Solidity performs calculations using integers,changeBpswill round down to-10, making it still valid to set even though the change is more than10 BPS; Recommendation(s): Consider rounding up when calculating the absolute changes in basis points. Here is a reference implementation for rounding up. Status: Acknowledged Update from the client: This is a great call out, but exclusively rounding up or down would have a loosening or tightening effect based on the situation. The slightly more correct option here would be to conditionally round up or down depending on which action would result in the tightest possible constraint. Due to how loose this constraint already is, we do not expect to ever be operating at these bounds; this decision should have no tangible outcome of the goals of the contract. We have decided not to implement “conditional” rounding as it is not worth the complexity. \*Example where rounding down loosens constraint.\* If RWA bps change is 84.9, and the CL bps change is 10, the 84.9 gets truncated to 84. Because 84-10 = 74, the price setting would succeed. \*Example where rounding down tightens constraint\* If RWA bps change is -85 and the CL bps change is -10.9, The -10.9 gets truncated to -10. Because -85 - -10 = -75, the price setting would fail. (If we rounded up it would have “loosened” constraint and passed) Update from Nethermind: We agree with your perspective that rounding should be situation-dependent. However, we believe it remains an issue, not a false positive. The provided examples occur becauseRWAOracleExternalComparisonCheckemploys two rounds of rounding (one for RWA BPS and one for Chainlink BPS), while in the case ofRWAOracleRateCheck, the change is rounded only once, and rounding up always tightens the constraints. Update from Client: PR to round up forRWAOracleRateCheck: a998c11559457b4d789cfda75903ee489f827cb9. 6.2 \[Low\] Changing oracle type does not remove previous oracle data File(s):contracts/lending/fluxOracles/FluxOracle.sol Description: TheFluxOraclecontract allows for the oracle type to be changed for each asset. However, when the oracle type is changed, the data previously stored in thefTokenToHardcodedPrice,fTokenToRWAOracle, andfTokenToChainlinkOraclemappings for the given asset is not removed. This can result in unintended behavior. It is good practice to remove unused data to prevent such issues and to save on gas costs. Below we presentsetFTokenToOracleType(...)function responsible for changing the oracle type: 1functionsetFTokenToOracleType( 2addressfToken, 3OracleType oracleType 4)externaloverride onlyRole(DEFAULT\_ADMIN\_ROLE) { 5fTokenToOracleType\[fToken\] = oracleType; 6////////////////////////////////////////////////////////////////////////////// 7// @audit Data from mappings fTokenToHardcodedPrice, fTokenToRWAOracle and // 8// fTokenToChainlinkOracle is not removed. // 9////////////////////////////////////////////////////////////////////////////// 10emit FTokenToOracleTypeSet(fToken, oracleType); 11} Recommendation(s): Consider removing any unused data when changing the oracle type for a given asset. Status: Fixed Update from the client: Cleared stale data in this PR: c39b3532de80600b201d801f28a699ae93bd07de. 7 NM-0081 ONDO FINANCE - SECURITY REVIEW 6.3 \[Low\] Lack of a two-step process for transferring ownership File(s):contracts/lending/fTokenOracle/fTokenOracle.sol Description: ThefTokenOraclecontract inherits OpenZeppelin’sOwnablecontract, which enables ownership to be transferred in a single step. However, this one-step transfer process can be prone to errors and may cause significant damage to the protocol if a mistake occurs. The function is presented below: 1////////////////////////////////////////////////////////////////////////////////////////// 2// @audit Providing an incorrect address will result in the immediate loss of ownership 3////////////////////////////////////////////////////////////////////////////////////////// 4functiontransferOwnership(addressnewOwner)publicvirtual onlyOwner { 5require(newOwner !=address(0), "Ownable: new owner is the zero address"); 6\_transferOwnership(newOwner); 7} Recommendation(s): We recommend implementing a two-step ownership transfer process, such as the propose-accept scheme. You can refer to the Ownable2Step.sol contract from OpenZeppelin for an example. Status: Fixed Update from the client: Added Ownable2Step in this PR: 0b86a1b554a8c345faef8b22045c718e52e2d533. 6.4 \[Low\] Use AccessControlDefaultAdminRules File(s):contracts/lending/rwaOracles/RWAOracleExternalComparisonCheck.sol,contracts/lending/rwaOracles/RWAOracleRateCheck.sol, contracts/lending/fluxOracles/FluxOracle.sol Description: TheFluxOracle,RWAOracleRateCheck, andRWAOracleExternalComparisonCheckcontracts inherit fromAccessControl. How- ever, theAccessControlcontract allows for potentially insecure behavior with theDEFAULT\_ADMIN\_ROLE, as multiple addresses can be granted this role and it is its own admin, meaning it has permission to grant and revoke the default admin role. A more secure solution is theAccessControlDefaultAdminRulescontract, which implements additional risk mitigations on top ofAccessControl: −only one account holds theDEFAULT\_ADMIN\_ROLEsince deployment until it’s potentially renounced; −enforces a 2-step process to transfer theDEFAULT\_ADMIN\_ROLEto another account; −enforces a configurable delay between the two steps, with the ability to cancel before the transfer is accepted; −the delay can be changed by scheduling; −it is not possible to use another role to manage theDEFAULT\_ADMIN\_ROLE; Recommendation(s): Consider usingAccessControlDefaultAdminRulesto increase the security of role management. Status: Acknowledged Update from the client: Understand the benefits ofAccessControlDefaultAdminRules; however, we don’t believe we need the added features/complexity at this point in time. 6.5 \[Low\]\_setFTokenToChainlinkOracle(...)does not check oracle decimals File(s):contracts/lending/fluxOracles/FluxOracle.sol Description: The\_setFTokenToChainlinkOracle(...)function assigns a specified Chainlink oracle to anfToken. However, there is no validation process in place to ensure that the number of decimals returned by the Chainlink oracle falls within an acceptable range. The function is presented below: 1function\_setFTokenToChainlinkOracle(addressfToken,addresschainlinkOracle,uint256maxChainlinkOracleTimeDelay ) private{↪ 2if(fTokenToOracleType\[fToken\] != OracleType.CHAINLINK) { 3revert InvalidOracleType( 4OracleType.CHAINLINK, 5fTokenToOracleType\[fToken\] 6); 7} 8addressunderlying = ICTokenLike(fToken).underlying(); 9fTokenToChainlinkOracle\[fToken\].scaleFactor = (10 \*\* (36 -uint256(IERC20Like(underlying).decimals()) - 10/////////////////////////////////////////////////////////////////////////////////// 11// @audit The decimals from Oracle are not checked 12/////////////////////////////////////////////////////////////////////////////////// 13uint256(AggregatorV3Interface(chainlinkOracle).decimals()))); 14fTokenToChainlinkOracle\[fToken\].oracle = AggregatorV3Interface(chainlinkOracle); 15fTokenToChainlinkOracle\[fToken\].maxChainlinkOracleTimeDelay = maxChainlinkOracleTimeDelay; 16} 8 NM-0081 ONDO FINANCE - SECURITY REVIEW Recommendation(s): Verify the number of decimals returned by the Chainlink oracle. Status: Acknowledged Update from the client: The contract works as intended in cases whereunderlyingDecimals + chainlinkDecimals <= 36. If the sum is > 36, the function will underflow. If the sum is == 36, the scaleFactor will be 1. If the sum is < 36, the scaleFactor will be some value >= 1e2. Check is not needed. Update from Nethermind: We believe that a check for decimals should be performed to ensure that the Chainlink response is not cor- rupted. This check would be consistent with the other checks for Chainlink response decimals in thefTokenOracleandRWAOracleExternalComparisonCheck contracts. 6.6 \[Info\] Events in RWA oracles differ File(s):contracts/lending/rwaOracles/RWAOracleRateCheck.sol,contracts/lending/rwaOracles/RWAOracleExternalComparisonCheck.sol Description: TheRWAOracleRateCheckandRWAOracleExternalComparisonCheckcontracts can both be assigned as oracles to anfToken with the same specified in theFluxOracle. As such, they are interchangeable. However, it should be noted that the events emitted when the price is set contain a varying number of fields. This discrepancy may pose a problem if these logs are utilized by off-chain infrastructure. The events in both contracts are presented below: 1/////////////////////////////////////////////////////////////////////////////////// 2// @audit RWAOracleRateCheck 3/////////////////////////////////////////////////////////////////////////////////// 4eventRWAPriceSet( 5int256oldPrice, 6int256newPrice, 7uint256timestamp 8); 1/////////////////////////////////////////////////////////////////////////////////// 2// @audit RWAOracleExternalComparisonCheck 3/////////////////////////////////////////////////////////////////////////////////// 4eventRWAPriceSet( 5int256oldChainlinkPrice, 6uint80indexed oldRoundId, 7int256newChainlinkPrice, 8uint80indexed newRoundId, 9int256oldRWAPrice, 10int256newRWAPrice 11); Recommendation(s): Maintain consistency in the number of fields included in the RWAPriceSet event. Alternatively, change the event names to correspond to the contracts that emit them. Status: Fixed Update from the client: We have changed the name of the event inRWAOracleExternalComparisonCheckin this commit. 22716a82e7382ab2479d6fe74f79d59e43879a65. 6.7 \[Info\] Inconsistent behavior onprice == 0 File(s):contracts/lending/fluxOracles/FluxOracle.sol Description: TheFluxOraclecontract supports three types of oracles: hardcoded, RWA, and Chainlink. However, these oracle types do not exhibit consistent behavior when the price is equal to0. Here is a summary of the behavior for each oracle type: −Hardcoded: The price can be set to and retrieved as0; −RWA: The oracle cannot be set if the returned price is0. The price can be retrieved as0; −Chainlink: The price can be retrieved as0(but reverts if less than0); This inconsistent behavior with zero values may lead to incorrect assumptions when using the oracles. While checking for a zero value when setting the RWA oracle is good practice, it creates an assumption that this oracle will always work correctly and does not check the returned price on a get call. Additionally, the price set for the hardcoded oracle is not checked and can be0. The Chainlink price is only considered invalid if it is less than0, allowing for0to be a valid price. Recommendation(s): Consider establishing a unified definition of a zero price for all types of oracles and implementing the set and get functions to behave consistently when the price is zero. Status: Fixed Update from the client: FluxOracle contract now prevents setting 0 price for Hardcoded type and retrieving zero prices for all oracle types. Fixed in: 48d5c4052795b082e876926f18f884927bb653b9. 9 NM-0081 ONDO FINANCE - SECURITY REVIEW 6.8 \[Info\] Incorrect check for decimals File(s):contracts/lending/rwaOracles/RWAOracleExternalComparisonCheck.sol Description: The constructor includes a check to ensure that the Chainlink oracle returns at least 4 decimals. The relevant code is shown below: 1constructor( 2int256initialPrice, 3address\_chainlinkOracle, 4stringmemory \_description, 5addressadmin, 6address\_setter 7) { 8chainlinkOracle = AggregatorV3Interface(\_chainlinkOracle); 9if(chainlinkOracle.decimals() < 4) revert CorruptedChainlinkResponse(); 10.... 11} However, it should be noted that the current minimum number of decimals returned by Chainlink is 8 for non-ETH pairs. In the event that the returned decimals are less than 8 but greater than 3, which could indicate a malfunction of Chainlink, this would not be detected by the contract. Recommendation(s): Consider checking if the decimals returned by Chainlink is 8. Status: Fixed Update from the client: We have changed the check todecimals==8in this commit. f983d5487e568016ad1ae2e4db72c2ec50d2b74d. 6.9 \[Info\] No check for fToken validity File(s):contracts/lending/fluxOracles/FluxOracle.sol Description: In theFluxOraclecontract, the oracle type can be assigned to anfTokenthrough thefTokenToOracleTypemapping. How- ever, there is no check in place to ensure that thefTokenis a valid address. This could be implemented in a similar manner to the fTokenOraclecontract: 1if(!IFToken(\_fToken).isCToken()) { 2revert InvalidFToken(); 3} Recommendation(s): Consider checking the validity of thefTokenwhen assigning the oracle type to the asset. Status: Fixed Update from the client: Check added in this PR: f19e5a38b78153ea436632f480b73194cdcda930. 6.10 \[Best Practice\] Use of magic numbers File(s):contracts/lending/fTokenOracle/fTokenOracle.sol Description: ThefTokenOraclecontract calculates thescaleFactorusing the following equation: 1/////////////////////////////////////////////////////////////////////////////////// 2// @audit Number 8 is not explained 3/////////////////////////////////////////////////////////////////////////////////// 4scaleFactor = 10 \*\* (priceFeedDecimals - 8 + fTokenUnderlyingDecimals); The constant8is used in the calculation, but its purpose is not explained. Recommendation(s): It is recommended to store constants as variables and provide a description that explains their purpose. This would improve the readability and maintainability of the code. Status: Fixed Update from the client: Removed magic number in this PR: 0b86a1b554a8c345faef8b22045c718e52e2d533. 10 NM-0081 ONDO FINANCE - SECURITY REVIEW 6.11 \[Best Practice\]renounceOwnership(...)function should be disabled File(s):contracts/lending/fTokenOracle/fTokenOracle.sol Description: ThefTokenOraclecontract, which is inherited from theOwnablecontract, includes therenounceOwnership(...)function. This function allows the owner to be removed from the contract. Below is a presentation of the function: 1/////////////////////////////////////////////////////////////////////////////////// 2// @audit Renouncing ownership will leave the contract without an owner 3/////////////////////////////////////////////////////////////////////////////////// 4functionrenounceOwnership()publicvirtual onlyOwner { 5\_transferOwnership(address(0)); 6} Recommendation(s): If thefTokenOracleis intended to operate with an owner, consider disabling therenounceOwnership(...)function. Status: Acknowledged Update from the client: 7 Documentation Evaluation Software documentation refers to the written or visual information that describes the functionality, architecture, design, and implementation of software. It provides a comprehensive overview of the software system and helps users, developers, and stakeholders understand how the software works, how to use it, and how to maintain it. Software documentation can take different forms, such as user manuals, system manuals, technical specifications, requirements documents, design documents, and code comments. Software documentation plays a critical role in software development, as it enables effective communication between developers, testers, users, and other stakeholders involved in the software development process. It helps to ensure that everyone involved in the development process has a shared understanding of the software system and its functionality. Moreover, software documentation can improve software maintenance by providing a clear and complete understanding of the software system, making it easier for developers to maintain, modify, and update the software over time. Smart contracts can use various types of software documentation. Some of the most common types include: −Technical whitepaper: A technical whitepaper is a comprehensive document that describes the design and technical details of the smart contract. It includes information about the purpose of the contract, its architecture, its components, and how they interact with each other; −User manual: A user manual is a document that provides information about how to use the smart contract. It includes step-by-step instructions on how to perform various tasks and explains the different features and functionalities of the contract; −Code documentation: Code documentation is a document that provides details about the code of the smart contract. It includes information about the functions, variables, and classes used in the code, as well as explanations of how they work; −API documentation: API documentation is a document that provides information about the API (Application Programming Interface) of the smart contract. It includes details about the methods, parameters, and responses that can be used to interact with the contract; −Testing documentation: Testing documentation is a document that provides information about how the smart contract was tested. It includes details about the test cases that were used, the results of the tests, and any issues that were identified during testing; −Audit documentation: Audit documentation includes reports, notes, and other materials related to the security audit of the smart contract. This type of documentation is critical in ensuring that the smart contract is secure and free from vulnerabilities. These types of documentation are essential for smart contract development and maintenance. They help ensure that the contract is properly designed, implemented, and tested, and they provide a reference for developers who need to modify or maintain the contract in the future. TheOndo Financeteam has provided extensive documentation in the Markdown format within the audit repository. This documentation encompasses a general overview of the protocol and detailed insights into each component. Additional documents about the mathematical logic behind certain aspects of the project were also shared. Moreover, the team conducted a comprehensive code walkthrough and maintained open communication to address any inquiries or concerns raised by the Nethermind auditors. 11 NM-0081 ONDO FINANCE - SECURITY REVIEW 8 Test Suite Evaluation The Ondo team has placed a significant focus on testing their code to ensure its quality. They have given particular attention to two essential testing methods: unit testing and fuzzing testing. For unit testing, they use the Forge testing framework, which helps them to thoroughly test individual components of their code in a controlled environment. Additionally, they use the Echidna tool for fuzzing testing. This involves generating random inputs to identify potential issues and edge cases. By employing both of these testing methods, the Ondo team can confidently guarantee that their code is reliable, resilient, and capable of handling a wide range of scenarios. 8.1 Contracts Compilation Output > forge build \[\] Compiling... \[\] Compiling 28 files with 0.5.17 \[\] Compiling 221 files with 0.8.16 \[\] Compiling 3 files with 0.6.12 \[\] Compiling 5 files with 0.8.7 \[\] Solc 0.6.12 finishedin46.28ms \[\] Solc 0.8.7 finishedin1.02s \[\] Solc 0.5.17 finishedin2.07s \[\] Solc 0.8.16 finishedin73.49s Compiler run successful (with warnings) 8.2 Tests Output > yarn test-forge-oracles Running 24 testsforRWAOracleExternalComparisonCheck.t.sol:RWAOracleExternalComparisonCheckTest \[PASS\] test\_absoluteDeviationAtLowerBound() (gas: 93031) \[PASS\] test\_absoluteDeviationAtUpperBound() (gas: 93374) \[PASS\] test\_absoluteDeviationOutsideLowerBound() (gas: 58557) \[PASS\] test\_absoluteDeviationOutsideUpperBound() (gas: 58544) \[PASS\] test\_bypassCheckCLLowerBound() (gas: 93367) \[PASS\] test\_bypassCheckCLLowerBoundFailure() (gas: 60407) \[PASS\] test\_bypassCheckCLTooHigh() (gas: 87472) \[PASS\] test\_bypassCheckCLTooLow() (gas: 89006) \[PASS\] test\_bypassCheckCLUpperBound() (gas: 93728) \[PASS\] test\_bypassCheckCLUpperBoundFailure() (gas: 60297) \[PASS\] test\_constructorFailNegativePrice() (gas: 73041) \[PASS\] test\_constructorFailRoundTooOld() (gas: 79151) \[PASS\] test\_constrainedSetter\_maxDeviationPositive() (gas: 25157) \[PASS\] test\_constrainedSetter\_setPrice() (gas: 28056) \[PASS\] test\_constrainedSetter\_setPrice\_fail\_accessControl() (gas: 75359) \[PASS\] test\_constrainedSetter\_setPrice\_fail\_negative() (gas: 10980) \[PASS\] test\_constrainedSetter\_setPrice\_fail\_tooLarge() (gas: 17111) \[PASS\] test\_constrainedSetter\_setPrice\_fail\_tooSmall() (gas: 17275) \[PASS\] test\_constrainedSetter\_setPrice\_fail\_tooSoon() (gas: 13070) \[PASS\] test\_constrainedSetter\_setPrice\_fail\_zeroPrice() (gas: 10912) \[PASS\] test\_fuzz\_multipleUpdates(uint256) (runs: 256, : 746114, ~: 747398) \[PASS\] test\_getPriceData() (gas: 29210) Test result: ok. 14 passed; 0 failed; finishedin2.20s Running 17 testsforforge-tests/lending/oracle/fTokenOracle/fUSDC-USD.t.sol:Test\_fUSDC\_USD\_Oracle\_ETH \[PASS\] test\_fTokenOracle\_description() (gas: 9816) \[PASS\] test\_fTokenOracle\_fail\_unsupportedPriceFeed() (gas: 403516) \[PASS\] test\_fTokenOracle\_getLatestPrice() (gas: 45048) \[PASS\] test\_fTokenOracle\_getLatestPrice\_fail\_negativePrice() (gas: 1030715) \[PASS\] test\_fTokenOracle\_getLatestPrice\_fail\_staleRound() (gas: 1010627) \[PASS\] test\_fTokenOracle\_getLatestPrice\_fail\_staleUpdateTime() (gas: 1031562) \[PASS\] test\_fTokenOracle\_getLatestPrice\_fail\_zeroPrice() (gas: 1010813) \[PASS\] test\_fTokenOracle\_getPrice() (gas: 44983) \[PASS\] test\_fTokenOracle\_getPrice\_fail\_negativePrice() (gas: 1030438) \[PASS\] test\_fTokenOracle\_getPrice\_fail\_zeroPrice() (gas: 1010623) \[PASS\] test\_fTokenOracle\_getPrice\_increase() (gas: 949811) \[PASS\] test\_fTokenOracle\_has\_owner() (gas: 7707) 12 NM-0081 ONDO FINANCE - SECURITY REVIEW \[PASS\] test\_fTokenOracle\_scaleFactor() (gas: 5537) \[PASS\] test\_fTokenOracle\_setMaxOracleTimeDelay() (gas: 19106) \[PASS\] test\_fTokenOracle\_setMaxOracleTimeDelay\_fail\_accessControl() (gas: 11404) \[PASS\] test\_fTokenOracle\_transferOwnership() (gas: 13470) \[PASS\] test\_fTokenOracle\_transferOwnership\_fail\_accessControl() (gas: 11496) Test result: ok. 17 passed; 0 failed; finishedin16.74s Running 17 testsforforge-tests/lending/oracle/fTokenOracle/fUSDC-ETH.t.sol:Test\_fUSDC\_ETH\_Oracle\_ETH \[PASS\] test\_fTokenOracle\_description() (gas: 9816) \[PASS\] test\_fTokenOracle\_fail\_unsupportedPriceFeed() (gas: 403516) \[PASS\] test\_fTokenOracle\_getLatestPrice() (gas: 48546) \[PASS\] test\_fTokenOracle\_getLatestPrice\_fail\_negativePrice() (gas: 1030715) \[PASS\] test\_fTokenOracle\_getLatestPrice\_fail\_staleRound() (gas: 1010627) \[PASS\] test\_fTokenOracle\_getLatestPrice\_fail\_staleUpdateTime() (gas: 1031562) \[PASS\] test\_fTokenOracle\_getLatestPrice\_fail\_zeroPrice() (gas: 1010813) \[PASS\] test\_fTokenOracle\_getPrice() (gas: 46239) \[PASS\] test\_fTokenOracle\_getPrice\_fail\_negativePrice() (gas: 1030438) \[PASS\] test\_fTokenOracle\_getPrice\_fail\_zeroPrice() (gas: 1010623) \[PASS\] test\_fTokenOracle\_getPrice\_increase() (gas: 949811) \[PASS\] test\_fTokenOracle\_has\_owner() (gas: 7707) \[PASS\] test\_fTokenOracle\_scaleFactor() (gas: 5537) \[PASS\] test\_fTokenOracle\_setMaxOracleTimeDelay() (gas: 19106) \[PASS\] test\_fTokenOracle\_setMaxOracleTimeDelay\_fail\_accessControl() (gas: 11404) \[PASS\] test\_fTokenOracle\_transferOwnership() (gas: 13470) \[PASS\] test\_fTokenOracle\_transferOwnership\_fail\_accessControl() (gas: 11496) Test result: ok. 17 passed; 0 failed; finishedin16.74s Running 26 testsforforge-tests/.../Test\_Flux\_Oracle\_RWAOracleExternalComparisonCheck \[PASS\] test\_fluxOracle\_accessControl() (gas: 36674) \[PASS\] test\_fluxOracle\_getChainlinkOraclePrice\_18Decimals() (gas: 491757) \[PASS\] test\_fluxOracle\_getChainlinkOraclePrice\_6Decimals() (gas: 503296) \[PASS\] test\_fluxOracle\_getChainlinkOraclePrice\_fail\_negativePrice() (gas: 494219) \[PASS\] test\_fluxOracle\_getChainlinkOraclePrice\_fail\_roundId() (gas: 474372) \[PASS\] test\_fluxOracle\_getChainlinkOraclePrice\_fail\_staleUpdate() (gas: 494499) \[PASS\] test\_fluxOracle\_getChainlinkOraclePrice\_fail\_updatedAt() (gas: 494272) \[PASS\] test\_fluxOracle\_getChainlinkOraclePrice\_fail\_zeroRoundId() (gas: 474317) \[PASS\] test\_fluxOracle\_getChainlinkOraclePrice\_fail\_zeroUpdatedAt() (gas: 454385) \[PASS\] test\_fluxOracle\_getTokenizedRWAPrice\_updatePrice() (gas: 148819) \[PASS\] test\_fluxOracle\_setFTokenToChainLinkOracle\_fail\_invalidType() (gas: 26291) \[PASS\] test\_fluxOracle\_setFTokenToChainlinkOracle() (gas: 128735) \[PASS\] test\_fluxOracle\_setFTokenToChainlinkOracle\_fail\_accessControl() (gas: 79944) \[PASS\] test\_fluxOracle\_setFTokenToOracleType\_chainlink() (gas: 22938) \[PASS\] test\_fluxOracle\_setFTokenToOracleType\_fail\_accessControl() (gas: 43072) \[PASS\] test\_fluxOracle\_setFTokenToOracleType\_hardcoded() (gas: 20095) \[PASS\] test\_fluxOracle\_setFTokenToOracleType\_tokenizedRWA() (gas: 20092) \[PASS\] test\_fluxOracle\_setFTokenToRWAOracle() (gas: 45197) \[PASS\] test\_fluxOracle\_setFTokenToRWAOracle\_fail\_accessControl() (gas: 79691) \[PASS\] test\_fluxOracle\_setFTokenToRWAOracle\_fail\_invalidType() (gas: 26781) \[PASS\] test\_fluxOracle\_setFTokenToRWAOracle\_fail\_notRWAOracle() (gas: 21131) \[PASS\] test\_fluxOracle\_setFTokenToRWAOracle\_invalidRWAOraclePrice() (gas: 26908) \[PASS\] test\_fluxOracle\_setHardcodedPrice() (gas: 32142) \[PASS\] test\_fluxOracle\_setHardcodedPrice\_fail\_accessControl() (gas: 77612) \[PASS\] test\_fluxOracle\_setHardcodedPrice\_fail\_invalidType() (gas: 24628) \[PASS\] test\_getUnderlying\_fail\_invalidType() (gas: 16445) Test result: ok. 26 passed; 0 failed; finishedin16.74s Running 26 testsforforge-tests/.../Test\_Flux\_Oracle\_Percent\_Constrained\_RWA\_Oracle \[PASS\] test\_fluxOracle\_accessControl() (gas: 36696) \[PASS\] test\_fluxOracle\_getChainlinkOraclePrice\_18Decimals() (gas: 491745) \[PASS\] test\_fluxOracle\_getChainlinkOraclePrice\_6Decimals() (gas: 503284) \[PASS\] test\_fluxOracle\_getChainlinkOraclePrice\_fail\_negativePrice() (gas: 494207) \[PASS\] test\_fluxOracle\_getChainlinkOraclePrice\_fail\_roundId() (gas: 474338) \[PASS\] test\_fluxOracle\_getChainlinkOraclePrice\_fail\_staleUpdate() (gas: 494487) \[PASS\] test\_fluxOracle\_getChainlinkOraclePrice\_fail\_updatedAt() (gas: 494260) \[PASS\] test\_fluxOracle\_getChainlinkOraclePrice\_fail\_zeroRoundId() (gas: 474305) \[PASS\] test\_fluxOracle\_getChainlinkOraclePrice\_fail\_zeroUpdatedAt() (gas: 454373) \[PASS\] test\_fluxOracle\_getTokenizedRWAPrice\_updatePrice() (gas: 83984) \[PASS\] test\_fluxOracle\_setFTokenToChainLinkOracle\_fail\_invalidType() (gas: 26336) 13 NM-0081 ONDO FINANCE - SECURITY REVIEW \[PASS\] test\_fluxOracle\_setFTokenToChainlinkOracle() (gas: 128735) \[PASS\] test\_fluxOracle\_setFTokenToChainlinkOracle\_fail\_accessControl() (gas: 79922) \[PASS\] test\_fluxOracle\_setFTokenToOracleType\_chainlink() (gas: 22938) \[PASS\] test\_fluxOracle\_setFTokenToOracleType\_fail\_accessControl() (gas: 43072) \[PASS\] test\_fluxOracle\_setFTokenToOracleType\_hardcoded() (gas: 20139) \[PASS\] test\_fluxOracle\_setFTokenToOracleType\_tokenizedRWA() (gas: 20092) \[PASS\] test\_fluxOracle\_setFTokenToRWAOracle() (gas: 45087) \[PASS\] test\_fluxOracle\_setFTokenToRWAOracle\_fail\_accessControl() (gas: 79691) \[PASS\] test\_fluxOracle\_setFTokenToRWAOracle\_fail\_invalidType() (gas: 26758) \[PASS\] test\_fluxOracle\_setFTokenToRWAOracle\_fail\_notRWAOracle() (gas: 21108) \[PASS\] test\_fluxOracle\_setFTokenToRWAOracle\_invalidRWAOraclePrice() (gas: 26930) \[PASS\] test\_fluxOracle\_setHardcodedPrice() (gas: 32164) \[PASS\] test\_fluxOracle\_setHardcodedPrice\_fail\_accessControl() (gas: 77634) \[PASS\] test\_fluxOracle\_setHardcodedPrice\_fail\_invalidType() (gas: 24628) \[PASS\] test\_getUnderlying\_fail\_invalidType() (gas: 16445) Test result: ok. 26 passed; 0 failed; finishedin16.74s Running 1 testforforge-tests/.../SHVOracleIntegration.t.sol:Test\_SHV\_Oracle\_Integration \[PASS\] test\_RWAOraclePriceUpdates() (gas: 357290) Test result: ok. 1 passed; 0 failed; finishedin25.12s 8.3 Code Coverage Unable to run code coverage. 8.4 Slither All the relevant issues raised by Slither have been incorporated into the issues described in this report. 14 NM-0081 ONDO FINANCE - SECURITY REVIEW 9 About Nethermind Nethermind is a Blockchain Research and Software Engineering company. Our work touches every part of the web3 ecosystem - from layer 1 and layer 2 engineering, cryptography research, and security to application-layer protocol development. We offer strategic support to our institutional and enterprise partners across the blockchain, digital assets, and DeFi sectors, guiding them through all stages of the research and development process, from initial concepts to successful implementation. We offer security audits of projects built on EVM-compatible chains and Starknet. We are active builders of the Starknet ecosystem, delivering a node implementation, a block explorer, a Solidity-to-Cairo transpiler, and formal verification tooling. Nethermind also provides strategic support to our institutional and enterprise partners in blockchain, digital assets, and decentralized finance (DeFi). In the next paragraphs, we introduce the company in more detail. Blockchain Security:At Nethermind, we believe security is vital to the health and longevity of the entire Web3 ecosystem. We pro- vide security services related to Smart Contract Audits, Formal Verification, and Real-Time Monitoring. Our Security Team comprises blockchain security experts in each field, often collaborating to produce comprehensive and robust security solutions. The team has a strong academic background, can apply state-of-the-art techniques, and is experienced in analyzing cutting-edge Solidity and Cairo smart contracts, such as ArgentX and StarkGate (the bridge connecting Ethereum and StarkNet). Most team members hold a Ph.D. degree and actively participate in the research community, accounting for 240+ articles published and 1,450+ citations in Google Scholar. The security team adopts customer-oriented and interactive processes where clients are involved in all stages of the work. Blockchain Core Development:Our core engineering team, consisting of over 20 developers, maintains, improves, and upgrades our flagship product - the Nethermind Ethereum Execution Client. The client has been successfully operating for several years, supporting both the Ethereum Mainnet and its testnets, and now accounts for nearly a quarter of all synced Mainnet nodes. Our unwavering commitment to Ethereum’s growth and stability extends to sidechains and layer 2 solutions. Notably, we were the sole execution layer client to facilitate Gnosis Chain’s Merge, transitioning from Aura to Proof of Stake (PoS), and we are actively developing a full-node client to bolster Starknet’s decentralization efforts. Our core team equips partners with tools for seamless node set-up, using generated docker-compose scripts tailored to their chosen execution client and preferred configurations for various network types. DevOps and Infrastructure Management:Our infrastructure team ensures our partners’ systems operate securely, reliably, and effi- ciently. We provide infrastructure design, deployment, monitoring, maintenance, and troubleshooting support, allowing you to focus on your core business operations. Boasting extensive expertise in Blockchain as a Service, private blockchain implementations, and node management, our infrastructure and DevOps engineers are proficient with major cloud solution providers and can host applications in- house or on clients’ premises. Our global in-house SRE teams offer 24/7 monitoring and alerts for both infrastructure and application levels. We manage over 5,000 public and private validators and maintain nodes on major public blockchains such as Polygon, Gnosis, Solana, Cosmos, Near, Avalanche, Polkadot, Aptos, and StarkWare L2. Sedge is an open-source tool developed by our infrastructure experts, designed to simplify the complex process of setting up a proof-of-stake (PoS) network or chain validator. Sedge generates docker- compose scripts for the entire validator set-up based on the chosen client, making the process easier and quicker while following best practices to avoid downtime and being slashed. Cryptography Research:At Nethermind, our Cryptography Research team is dedicated to continuous internal research while fostering close collaboration with external partners. The team has expertise across a wide range of domains, including cryptography protocols, consensus design, decentralized identity, verifiable credentials, Sybil resistance, oracles, and credentials, distributed validator technology (DVT), and Zero-knowledge proofs. This diverse skill set, combined with strong collaboration between our engineering teams, enables us to deliver cutting-edge solutions to our partners and clients. Smart Contract Development & DeFi Research:Our smart contract development and DeFi research team comprises 40+ world-class engineers who collaborate closely with partners to identify needs and work on value-adding projects. The team specializes in Solidity and Cairo development, architecture design, and DeFi solutions, including DEXs, AMMs, structured products, derivatives, and money market protocols, as well as ERC20, 721, and 1155 token design. Our research and data analytics focuses on three key areas: technical due diligence, market research, and DeFi research. Utilizing a data-driven approach, we offer in-depth insights and outlooks on various industry themes. Our suite of L2 tooling:Warp is Starknet’s approach to EVM compatibility. It allows developers to take their Solidity smart contracts and transpile them to Cairo, Starknet’s smart contract language. In the short time since its inception, the project has accomplished many achievements, including successfully transpiling Uniswap v3 onto Starknet using Warp. −Voyageris a user-friendly Starknet block explorer that offers comprehensive insights into the Starknet network. With its intuitive interface and powerful features, Voyager allows users to easily search for and examine transactions, addresses, and contract details. As an essential tool for navigating the Starknet ecosystem, Voyager is the go-to solution for users seeking in-depth information and analysis; −Horusis an open-source formal verification tool for StarkNet smart contracts. It simplifies the process of formally verifying Starknet smart contracts, allowing developers to express various assertions about the behavior of their code using a simple assertion language; −Junois a full-node client implementation for Starknet, drawing on the expertise gained from developing the Nethermind Client. Written in Golang and open-sourced from the outset, Juno verifies the validity of the data received from Starknet by comparing it to proofs retrieved from Ethereum, thus maintaining the integrity and security of the entire ecosystem. Learn more about us at nethermind.io. 15 NM-0081 ONDO FINANCE - SECURITY REVIEW Disclaimer This report is based on the scope of materials and documentation provided by you to Nethermind in order that Nethermind could conduct the security review outlined in1. Executive Summaryand2. Audited Files. The results set out in this report may not be complete nor inclusive of all vulnerabilities. Nethermind has provided the review and this report on an as-is, where-is, and as-available basis. You agree that your access and/or use, including but not limited to any associated services, products, protocols, platforms, content, and materials, will be at your sole risk. Blockchain technology remains under development and is subject to unknown risks and flaws. The review does not extend to the compiler layer, or any other areas beyond the programming language, or other programming aspects that could present security risks. This report does not indicate the endorsement of any particular project or team, nor guarantee its security. No third party should rely on this report in any way, including for the purpose of making any decisions to buy or sell a product, service or any other asset. To the fullest extent permitted by law, Nethermind disclaims any liability in connection with this report, its content, and any related services and products and your use thereof, including, without limitation, the implied warranties of merchantability, fitness for a particular purpose, and non-infringement. Nethermind does not warrant, endorse, guarantee, or assume responsibility for any product or service advertised or offered by a third party through the product, any open source or third-party software, code, libraries, materials, or information linked to, called by, referenced by or accessible through the report, its content, and the related services and products, any hyperlinked websites, any websites or mobile applications appearing on any advertising, and Nethermind will not be a party to or in any way be responsible for monitoring any transaction between you and any third-party providers of products or services. As with the purchase or use of a product or service through any medium or in any environment, you should use your best judgment and exercise caution where appropriate. FOR AVOIDANCE OF DOUBT, THE REPORT, ITS CONTENT, ACCESS, AND/OR USAGE THEREOF, INCLUDING ANY ASSOCIATED SERVICES OR MATERIALS, SHALL NOT BE CONSIDERED OR RELIED UPON AS ANY FORM OF FINANCIAL, INVESTMENT, TAX, LEGAL, REGULATORY, OR OTHER ADVICE. 16
---
# Unknown
September 3rd 2021— Quantstamp Verified Ondo Finance V2 This audit report was prepared by Quantstamp, the leader in blockchain security. Executive Summary Type Yield Aggregator Strategy Auditors Leonardo Passos,Senior Research Engineer Fayçal Lalidji,Security Auditor Timeline 2021-08-23through2021-09-03 EVM Muir Glacier Languages Solidity Methods Architecture Review, Unit Testing, Functional Testing, Computer-Aided Verification, Manual Review Specification None Documentation Quality Low Test Quality Low Source Code RepositoryCommit protocol-dev610a629 Total Issues 15(0 Resolved) High Risk Issues 0(0 Resolved) Medium Risk Issues 4(0 Resolved) Low Risk Issues 6(0 Resolved) Informational Risk Issues 4(0 Resolved) Undetermined Risk Issues 1(0 Resolved) High Risk The issue puts a large number of users’ sensitive information at risk, or is reasonably likely to lead to catastrophic impact for client’s reputation or serious financial implications for client and users. Medium Risk The issue puts a subset of users’ sensitive information at risk, would be detrimental for the client’s reputation if exploited, or is reasonably likely to lead to moderate financial impact. Low Risk The risk is relatively small and could not be exploited on a recurring basis, or is a risk that the client has indicated is low- impact in view of the client’s business circumstances. Informational The issue does not post an immediate risk, but is relevant to security best practices or Defence in Depth. Undetermined The impact of the issue is uncertain. Unresolved Acknowledged the existence of the risk, and decided to accept it without engaging in special efforts to control it. Acknowledged The issue remains in the code but is a result of an intentional business or design decision. As such, it is supposed to be addressed outside the programmatic means, such as: 1) comments, documentation, README, FAQ; 2) business processes; 3) analyses showing that the issue shall have no negative consequences in practice (e.g., gas analysis, deployment settings). Resolved Adjusted program implementation, requirements or constraints to eliminate the risk. Mitigated Implemented actions to minimize the impact or likelihood of the risk. Summary of Findings Through reviewing the code, we foundof various levels of severity. We recommend addressing the findings prior to deploying the smart contracts to the main network.16 potential issues IDDescriptionSeverityStatus QSP-1 Mid-Term Lp Deposits Allow For Risk-Free Profits Medium Unresolved QSP-2 Use of Magic Numbers Dependent on External Protocol Fees Medium Unresolved QSP-3 Possible Truncation While Calculating Vault Deposits Shares Medium Unresolved QSP-4 Possible Incorrect Path Reward Update Medium Unresolved QSP-5 Privileged Roles and Ownership Low Unresolved QSP-6 Potential Division by an Extremely Small Value Low Unresolved QSP-7 Harvest Is Not Affected by Pausing Low Unresolved QSP-8 Allows Circular Paths updateRewardPath Low Unresolved QSP-9 MisingValidation isContract Low Unresolved QSP-10 Lp Removal Does Not Validate Target Address Low Unresolved QSP-11 Clone and Own (1) Informational Unresolved QSP-12 Clone and Own (2) Informational Unresolved QSP-13 Vault Shares Update Does Not Follow the Same Pattern Informational Unresolved QSP-14 Possible Transaction Revert Due to Sandwich Attack Informational Unresolved QSP-15 Incorrect Path Validation Logic Undetermined Unresolved QuantstampAuditBreakdown Quantstamp's objective was to evaluate the repository for security-related issues, code quality, and adherence to specification and best practices. Possible issues we looked for included (but are not limited to): Transaction-ordering dependence• Timestamp dependence• Mishandled exceptions and call stack limits• Unsafe external calls• Integer overflow / underflow• Number rounding errors• Reentrancy and cross-function vulnerabilities• Denial of service / logical oversights• Access control• Centralization of power• Business logic contradicting the specification• Code clones, functionality duplication• Gas usage• Arbitrary token minting• Methodology The Quantstampauditingprocess follows a routine series of steps: 1.Code review that includes the following i.Review of the specifications, sources, and instructions provided to Quantstamp to make sure we understand the size, scope, and functionality of the smart contract. ii.Manual review of code, which is the process of reading source code line-by-line in an attempt to identify potential vulnerabilities. iii.Comparison to specification, which is the process of checking whether the code does what the specifications, sources, and instructions provided to Quantstamp describe. 2.Testing and automated analysis that includes the following: i.Test coverage analysis, which is the process of determining whether the test cases are actually covering the code and how much code is exercised when we run those test cases. ii.Symbolic execution, which is analyzing a program to determine what inputs cause each part of a program to execute. 3.Best practices review, which is a review of the smart contracts to improve efficiency, effectiveness, clarify, maintainability, security, and control based on the established industry and academic practices, recommendations, and research. 4.Specific, itemized, and actionable recommendations to help you take steps to secure your smart contracts. Toolset The notes below outline the setup and steps performed in the process of thisaudit. Setup Tool Setup: v0.8.0•Slither Steps taken to run the tools: Installed the Slither tool:Run Slither from the project directory:pip install slither-analyzerslither . Findings QSP-1 Mid-Term Lp Deposits Allow For Risk-Free Profits Severity:Medium Risk UnresolvedStatus: File(s) affected:SushiStakingV2Strategy.sol An attacker can sandwich-attack every timeis called by mid-term depositing LP tokens before the harvest (receiving tranche tokens). The attacker proceeds to withdraw the tranche share tokens for an increased amount of LP tokens. Description:SushiStakingV2Strategy.harvest(...) 1. Attacker observes a pending harvest function by the strategistExploit Scenario: 1.Attacker deposits LP tokens using. The latter invokes, which gets being resolved to . The attacker receives tranche tokens representing a fair share of the current LP tokens of the strategy AllPairVault.depositLp(...)Strategy.addLp(...) SushiStakingV2Strategy.addLp(...) 2.Harvest happens, increasing the total LP tokens of the strategy 3.Attacker redeems their tranche tokens from step (2) by calling(calling) and receives more LP tokens than initially due to the increase in (3). AllPairVault.withdrawLp(...)Strategy.removeLp(...) We recommend compounding the rewards before assigning the shares to a possible attacker.Recommendation: QSP-2 Use of Magic Numbers Dependent on External Protocol Fees Severity:Medium Risk UnresolvedStatus: File(s) affected:SushiStakingV2Strategy.sol The constants used in thefunction depend on the fees charged by Uniswap and SushiSwap. Changes in fees by these protocols would lead to incorrect calculations. Description:calculateSwapInAmount() Parameterize the contract s.t. one could make updates to the fee values as needed.Recommendation: QSP-3 Possible Truncation While Calculating Vault Deposits Shares Severity:Medium Risk UnresolvedStatus: File(s) affected:SushiStakingV2Strategy.sol The implemented staking mechanism inis highly optimized and helps avoid any extra computation. However, setting the values of the initial shares for a specific pool is important and should be analyzed carefully. Description:SushiStakingV2Strategy The algorithm is designed in a way to compute smaller shares every time that the LP rewards get higher, meaning that depositing the same LP tokens values for a specific vault will result in giving different shares values (while the reward is accruing). However, if the initial deposit is low enough and if the LP rewards are significantly greater than the initial LP deposit, new deposits to the vault will see their computed share being truncated. In a worst-case scenario, if for any reason higher LP rewards can be introduced by an attacker, the next deposits will be truncated following the value of rewards introduced. The attacker will profit by getting higher returns. This issue can be solved by multiplying the initial amount by a constant multiplier inL496 and L498. The value of the multiplier should be determined following the smallest possible investment, for example, if the smallest possible investment is 1 Wei, we would recommend a multiplier of. Recommendation:depositIntoChef 10\*\*18 QSP-4 Possible Incorrect Path Reward Update Severity:Medium Risk UnresolvedStatus: File(s) affected:SushiStakingV2Strategy.sol requirement inseems incorrect since in the case if reward token and end token are similar the required length is set to be higher than 1, meaning that resetting a path length equal to 1 is not allowed. Description:updateRewardPathL282 The team should confirm if this behavior was intended since the requirement looks like it has to be changed to check if the length is equal to one when both reward and end token are equal. Recommendation: QSP-5 Privileged Roles and Ownership Severity:Low Risk UnresolvedStatus: File(s) affected:SushiStakingV2Strategy.sol Many operations inrely on a strategist role.Description:SushiStakingV2Strategy A vault's strategist is responsible for correctly executing most of the vault and strategy actions and needs to be trusted. Even when assuming full trust in strategists,would be at risk if strategists get compromised.SushiStakingV2Strategy Document the trust assumptions for the strategist role and consider using a multi-sig defence.Recommendation: QSP-6 Potential Division by an Extremely Small Value Severity:Low Risk UnresolvedStatus: File(s) affected:SushiStakingV2Strategy.sol Thecallsbefore reaching the block in L497-500, in which the following calculation s performed:Description:SushiStakingV2Strategy.depositIntoChef(...)\_compound() uint256 shares = (\_amount \* poolData.totalShares) / poolData.totalLp Ifis an extremely small value (for example, because of some dust generated from calling), this may lead to an extremely large value being stored in the variable. A similar issue is present in. poolData.totalLp\_compound() shareswithdrawFromChef(...) Consider writing several test cases in which these code blocks are reached to ensure intended behavior.Recommendation: QSP-7 Harvest Is Not Affected by Pausing Severity:Low Risk UnresolvedStatus: File(s) affected:SushiStakingV2Strategy.sol To allow reacting to a potential hack, it is always a good practice to allow pausing a contract. However,can still be called when the contract is paused. Note that the latter calls, which is itself not affected by any pauses. Hence, one can invokewhile the strategy is paused. That should not be allowed, especially in the case of reacting to a hack. Description:SushiStakingV2Strategy.harvest(...) \_compoundharvest(...) Add themodifier to.Recommendation:whenNotPausedSushiStakingV2Strategy.harvest(...) QSP-8Allows Circular Paths updateRewardPath Severity:Low Risk UnresolvedStatus: File(s) affected:SushiStakingV2Strategy.sol Thefunction allows paths with lengths greater than one, yet, with the reward and end token being the same (circular). It is just wasteful to trade a token for itself. Description:SushiStakingV2Strategy.updateRewardPath(...) At the code level (L278--281), this appears as follows: L278. require( L279. rewardToken != endToken || \_pathFromReward.length > 1, <=== L280. "Invalid path" ); Forto be evaluated,must be the same as, in which case the length is already greater than one. Otherwise, if , the length should be exactly one, which is not the condition being checked. \_pathFromReward.length > 1rewardTokenendTokenrewardToken == endToken Change L278--281 to:Recommendation: require( rewardToken != endToken || \_pathFromReward.length == 1, "Invalid path" ); QSP-9 MisingValidation isContract Severity:Low Risk UnresolvedStatus: ,File(s) affected:AlchemixUserReward.solSushiStakingV2Strategy.sol The constructor ofdoes not validate whether the input addresses are indeed contracts; same with and. Hence, incorrect setups could lead the contract to misbehave. Description:SushiStakingV2StrategySushiStakingV2Strategy.addPool(...) AlchemixUserReward.constructor(...) As mitigation, add a check requiring that all provided addresses that should refer to a contract pass thecheck. Alternatively, make sure your deployment scripts assert that the given addresses refer to the contract addresses expected by. Recommendation:Address.isContract(...) SushiStakingV2Strategy.constructor(...) QSP-10 Lp Removal Does Not Validate Target Address Severity:Low Risk UnresolvedStatus: File(s) affected:SushiStakingV2Strategy.sol Thedoes not validate itsargument. If, the removal essentially burn funds.Description:SushiStakingV2Strategy.removeLp(...)toaddress(0) Add astatement to ensure theaddress is not.Recommendation:requireto0x0 QSP-11 Clone and Own (1) Severity:Informational UnresolvedStatus: File(s) affected:SushiStakingV2Strategy.sol Functionappears to have been cloned from Alpha Homora and Zapper, but the inline code comment does not indicate the commit hash and file from which it was taken. If buggy, faulty behavior may be permanently set in unless one is able to trace the code and corresponding fixes that might surface. Description:calculateSwapInAmount(...) Link the cloned code with its source so one can trace potential bugs and patches, periodically pulling the latter whenever available.Recommendation: QSP-12 Clone and Own (2) Severity:Informational UnresolvedStatus: File(s) affected:SushiStakingV2Strategy.sol Contractshares a lot of commonality with, but duplicated code appears in both contracts. Not only this adds extra maintenance, but also can lead to incorrect bug fixing if fixes are done in one strategy, but not the other. Description:SushiStakingV2StrategySushiStrategyLP Refactor duplicated code inandin a base contract that gets inherited by both.Recommendation:SushiStakingV2StrategySushiStrategyLP QSP-13 Vault Shares Update Does Not Follow the Same Pattern Severity:Informational UnresolvedStatus: File(s) affected:SushiStakingV2Strategy.sol does not accumulate the vault shares but rewrites them, using the input value. This scheme is not used any of the other functions that update the shares. Even ifcan be called only once, developers should be careful with future contract updates. Description:depositIntoChef() depositIntoChef We recommend to accumulates its value rather than resetting it.Recommendation: QSP-14 Possible Transaction Revert Due to Sandwich Attack Severity:Informational UnresolvedStatus: Not including the minimum out values and setting its value to zero when executing an external call to Sushiswap might result in a failing transaction due to bots not recognizing that a transaction may fail later on. This issue depends on how the attack bots are implemented. Description: QSP-15 Incorrect Path Validation Logic Severity:Undetermined UnresolvedStatus: File(s) affected:SushiStakingV2Strategy.sol Thearray should have two paths. It seems one path should end inand the other in(or vice-versa). However, the implementation in , both paths could end inor. It is unclear if the latter situation is indeed desired; our understanding is thatthe first case should be allowed. Description:rewardPathstoken0token1 SushiStakingV2Strategy.addPool(...)token0token1only Clarify this issue with better documentation in the code. If the current implementation is incorrect, then require that both paths have distinct ends, one ending inand the other in. Recommendation:token0 token1 Automated Analyses Slither Slither did not report any significant issues. Adherence to Best Practices In, make sure to add descriptive messages for the require statements. For exaample, could be restated as. • SushiStakingV2Strategy.solrequire(\_router != address(0), "Invalid address")require(\_router != address(0), "Invalid router address") make use of magic constants whose purpose is unclear to readers. Please provide supporting documentation.• SushiStakingV2Strategy.sol Unused storage variable. Consider removing it.• SushiStakingV2Strategy.xSushi Unused function. Consider removing it.• SushiStakingV2Strategy.getSushiPath(...) Message inat L245 is misleading, as it could be the case that both the first element in the first and second paths are sushi. In the latter case, although the first path would be sushi, the error message would report the contrary. • SushiStakingV2Strategy.sol Functionis too large. Consider refactoring it.• SushiStakingV2Strategy.\_compound(...) It seemsdoes not need to be marked, as it does not contain any external calls.• SushiStakingV2Strategy.updateRewardPath(...)nonReentrant Test Results Test Suite Results npx hardhat test Creating Typechain artifacts in directory typechain for target ethers-v5 Successfully generated Typechain artifacts! masterchefv2 dual incentive pool mcv2 vault lifecycle ✓ get assets (17270ms) ✓ create vaults (2589ms) ✓ deposit assets and fast-forward (9608ms) ✓ invest ALCX/ETH vault (39481ms) ✓ invest ETH/ALCX vault (8186ms) ✓ harvest (322ms) ✓ harvest (392ms) ✓ harvest (395ms) ✓ harvest (254ms) ✓ harvest (370ms) ✓ harvest (315ms) ✓ redeem ALCX/ETH vault (3159ms) ✓ redeem ETH/ALCX vault (659ms) Claim ✓ Create vault (2652ms) ✓ Get some DAI ✓ Deposit on both sides (11363ms) ✓ Move to invest state (4894ms) ✓ Try to claim DAI ✓ Try to claim ETH ✓ Redeem funds (2593ms) ✓ Withdraw all funds (74ms) Create2 ✓ create Vault (1800ms) Performance fees delayed Vault ✓ setup vault fixture (3577ms) ✓ create vault (1394ms) ✓ can only deposit after start time (1345ms) ✓ setup fee collector and performance fee ✓ deposits after start time (77ms) ✓ invest and redeem (194ms) Ondo metadata ✓ has a name ✓ has a symbol balanceOf ✓ grants to initial account delegateBySig ✓ reverts if the signatory is invalid (528ms) ✓ reverts if the nonce is bad ✓ reverts if the signature has expired ✓ delegates on behalf of the signatory numCheckpoints ✓ returns the number of checkpoints for a delegate (80ms) Ondo transfer disabled ✓ transfer reverts when transfers are disabled ✓ account with transfer role can transfer ✓ transferAllowed works correctly Registry ✓ grant roles ✓ register contracts Rescue functions pause and rescue asset and LP tokens ✓ doesn't allow rescuing tokens outside of pause mode ✓ pauses and freezes Vault functions (74ms) ✓ rescue tokens (57ms) ✓ stops the pause and restores functionality test reverts ✓ reverts (1723ms) RolloverVault basic rollover ✓ create rollover (2640ms) ✓ create rollover from existing Vault (3795ms) ✓ deposit senior asset (157ms) ✓ deposit exceeds senior user cap (50ms) ✓ deposit junior asset (180ms) ✓ adds another Vault to rollover tip (1304ms) ✓ migrate (182ms) ✓ single deposit (54ms) ✓ deposit senior asset (184ms) ✓ deposit exceeds senior user cap (47ms) ✓ deposit junior asset (186ms) ✓ adds another Vault to rollover tip (1245ms) ✓ migrate (299ms) ✓ deposit senior asset (155ms) ✓ deposit exceeds senior user cap (44ms) ✓ deposit junior asset (159ms) ✓ adds another Vault to rollover tip (1326ms) ✓ migrate (278ms) ✓ single deposit (51ms) ✓ deposit senior asset (227ms) ✓ deposit exceeds senior user cap (59ms) ✓ deposit junior asset (178ms) ✓ adds another Vault to rollover tip (1532ms) ✓ migrate (306ms) ✓ deposit senior asset (253ms) ✓ deposit exceeds senior user cap (50ms) ✓ deposit junior asset (163ms) ✓ adds another Vault to rollover tip (1298ms) ✓ migrate (283ms) ✓ doesn't send additional excess on deposit after claiming ✓ withdraw (94ms) ✓ deposit senior asset (177ms) ✓ deposit exceeds senior user cap (42ms) ✓ deposit junior asset (161ms) ✓ adds another Vault to rollover tip (1330ms) ✓ migrate (296ms) StakingPools ✓ should set correct state variables (523ms) ✓ should allow emergency withdraw (197ms) ✓ should give out ondos only after farming time (1093ms) ✓ should not distribute ONDOs if no one deposit (602ms) ✓ should distribute ondos properly for each staker (1302ms) ✓ should give proper ONDOs allocation to each pool (835ms) ✓ should stop giving bonus ONDOs after the bonus period ends (1079ms) ✓ should track minimumOndoRequiredBalance properly (903ms) SushiStrategyLP ✓ pool add and update reverts (18253ms) batchCreate ✓ create Vault: sell senior for leveraged junior returns (1255ms) ✓ create Vault: sell all junior to partially cover senior (1297ms) ✓ create Vault: sell some junior to cover senior (1371ms) batchDeposit ✓ deposit senior asset: sell senior for leveraged junior returns (92ms) ✓ deposit junior asset: sell senior for leveraged junior returns (87ms) ✓ deposit senior asset: sell all junior to partially cover senior (90ms) ✓ deposit junior asset: sell all junior to partially cover senior (87ms) ✓ deposit senior asset: sell some junior to cover senior (88ms) ✓ deposit junior asset: sell some junior to cover senior (88ms) increase time ✓ increase time batchInvest ✓ invest assets: sell senior for leveraged junior returns (6703ms) ✓ invest assets: sell all junior to partially cover senior (1192ms) ✓ invest assets: sell some junior to cover senior (229ms) increase time ✓ increase time batchMidDeposit ✓ deposit LP tokens mid-duration with signer 4: sell senior for leveraged junior returns (1199ms) ✓ deposit LP tokens mid-duration with signer 4: sell all junior to partially cover senior (548ms) ✓ deposit LP tokens mid-duration with signer 4: sell some junior to cover senior (525ms) batchMidDeposit ✓ deposit LP tokens mid-duration with signer 5: sell senior for leveraged junior returns (517ms) ✓ deposit LP tokens mid-duration with signer 5: sell all junior to partially cover senior (522ms) ✓ deposit LP tokens mid-duration with signer 5: sell some junior to cover senior (526ms) increase time ✓ increase time batchHarvest ✓ harvest rewards: sell senior for leveraged junior returns (166ms) ✓ harvest rewards: sell all junior to partially cover senior (368ms) ✓ harvest rewards: sell some junior to cover senior (167ms) batchMidWithdraw ✓ withdraw LP mid-duration with signer 4: sell senior for leveraged junior returns (109ms) ✓ withdraw LP mid-duration with signer 4: sell all junior to partially cover senior (101ms) ✓ withdraw LP mid-duration with signer 4: sell some junior to cover senior (112ms) batchMidDeposit ✓ deposit LP tokens mid-duration with signer 6: sell senior for leveraged junior returns (528ms) ✓ deposit LP tokens mid-duration with signer 6: sell all junior to partially cover senior (528ms) ✓ deposit LP tokens mid-duration with signer 6: sell some junior to cover senior (510ms) batchHarvest ✓ harvest rewards: sell senior for leveraged junior returns (161ms) ✓ harvest rewards: sell all junior to partially cover senior (170ms) ✓ harvest rewards: sell some junior to cover senior (165ms) increase time ✓ increase time batchClaim ✓ claim tranche tokens: sell senior for leveraged junior returns (148ms) ✓ claim tranche tokens: sell all junior to partially cover senior (144ms) ✓ claim tranche tokens: sell some junior to cover senior (88ms) redeem and withdrawal: sell senior for leveraged junior returns ✓ redeem LP after fee accrual (329ms) ✓ withdraw received amounts (291ms) redeem and withdrawal: sell all junior to partially cover senior ✓ redeem LP after fee accrual (311ms) ✓ withdraw received amounts (281ms) redeem and withdrawal: sell some junior to cover ✓ redeem LP after fee accrual (473ms) ✓ withdraw received amounts (302ms) final sanity check ✓ pool totallp and totalshares is zero works with sushi as token in pair being farmed batchCreate ✓ create Vault: sell senior for leveraged junior returns (1244ms) ✓ create Vault: sell all junior to partially cover senior (1321ms) ✓ create Vault: sell some junior to cover senior (1134ms) batchDeposit ✓ deposit senior asset: sell senior for leveraged junior returns (4697ms) ✓ deposit junior asset: sell senior for leveraged junior returns (90ms) ✓ deposit senior asset: sell all junior to partially cover senior (60ms) ✓ deposit junior asset: sell all junior to partially cover senior (94ms) ✓ deposit senior asset: sell some junior to cover senior (62ms) ✓ deposit junior asset: sell some junior to cover senior (89ms) increase time ✓ increase time batchInvest ✓ invest assets: sell senior for leveraged junior returns (1488ms) ✓ invest assets: sell all junior to partially cover senior (215ms) ✓ invest assets: sell some junior to cover senior (338ms) increase time ✓ increase time batchMidDeposit ✓ deposit LP tokens mid-duration with signer 4: sell senior for leveraged junior returns (535ms) ✓ deposit LP tokens mid-duration with signer 4: sell all junior to partially cover senior (497ms) ✓ deposit LP tokens mid-duration with signer 4: sell some junior to cover senior (497ms) batchMidDeposit ✓ deposit LP tokens mid-duration with signer 5: sell senior for leveraged junior returns (504ms) ✓ deposit LP tokens mid-duration with signer 5: sell all junior to partially cover senior (536ms) ✓ deposit LP tokens mid-duration with signer 5: sell some junior to cover senior (521ms) increase time ✓ increase time batchHarvest ✓ harvest rewards: sell senior for leveraged junior returns (246ms) ✓ harvest rewards: sell all junior to partially cover senior (235ms) ✓ harvest rewards: sell some junior to cover senior (143ms) batchMidWithdraw ✓ withdraw LP mid-duration with signer 4: sell senior for leveraged junior returns (111ms) ✓ withdraw LP mid-duration with signer 4: sell all junior to partially cover senior (114ms) ✓ withdraw LP mid-duration with signer 4: sell some junior to cover senior (100ms) batchMidDeposit ✓ deposit LP tokens mid-duration with signer 6: sell senior for leveraged junior returns (522ms) ✓ deposit LP tokens mid-duration with signer 6: sell all junior to partially cover senior (500ms) ✓ deposit LP tokens mid-duration with signer 6: sell some junior to cover senior (498ms) batchHarvest ✓ harvest rewards: sell senior for leveraged junior returns (143ms) ✓ harvest rewards: sell all junior to partially cover senior (138ms) ✓ harvest rewards: sell some junior to cover senior (141ms) increase time ✓ increase time batchClaim ✓ claim tranche tokens: sell senior for leveraged junior returns (85ms) ✓ claim tranche tokens: sell all junior to partially cover senior (81ms) ✓ claim tranche tokens: sell some junior to cover senior (91ms) redeem and withdraw ✓ redeem LP after fee accrual (3694ms) alchemix alchemix vault lifecycle ✓ get assets (239ms) ✓ add pool ✓ create vaults (2969ms) ✓ deposit assets and fast-forward (10059ms) ✓ invest ALCX/ETH vault (9733ms) ✓ invest ETH/ALCX vault (1122ms) ✓ harvest (242ms) ✓ harvest (357ms) ✓ harvest (428ms) ✓ harvest (413ms) ✓ harvest (398ms) ✓ harvest (379ms) ✓ redeem ALCX/ETH vault (2398ms) ✓ redeem ETH/ALCX vault (573ms) TrancheToken ✓ spin up tranche tokens on Vault creation (1381ms) ✓ deposit base assets during Deposit phase (109ms) ✓ claim tokens only after investment (141ms) ✓ approve and transferFrom Uni ✓ test create mock (5161ms) ✓ test uniPull (484ms) AllPairVault delayed Vault ✓ setup vault fixture (419ms) ✓ create vault (1496ms) ✓ can only deposit after start time (1281ms) ✓ can get multiple vaults back from getVault (4207ms) ✓ deposits after start time (63ms) ✓ deposits exceed user cap ✓ deposits exceed tranche cap (103ms) ✓ can't deposit after investment withdraw midterm LP deposit ✓ setup vault fixture (2361ms) ✓ create vault (1647ms) ✓ deposit senior asset (115ms) ✓ deposit junior asset (122ms) ✓ deposits as expected ✓ cannot invest too early ✓ invest assets (87ms) ✓ can't deposit or withdraw midterm unless tranche tokens are enabled ✓ deposit LP tokens mid-duration with signer 7 (330ms) ✓ withdraws as expected after depositing LP without claiming (188ms) ✓ withdraw received amounts (149ms) sell senior for leveraged junior returns ✓ setup vault fixture (3994ms) ✓ create vault (1380ms) ✓ deposit senior asset (136ms) ✓ deposit junior asset (126ms) ✓ deposits as expected ✓ cannot invest too early ✓ gets Vault by tranche token addresses ✓ gets all Vaults ✓ invest assets (97ms) ✓ claim tranche tokens and excess (150ms) ✓ withdraw LP mid-duration from original deposits (217ms) ✓ deposit LP tokens mid-duration with signer 6 (379ms) ✓ deposit LP tokens mid-duration with signer 7 (361ms) ✓ withdraw LP mid-duration with signer 6 (73ms) ✓ withdraw LP mid-duration with signer 7 (70ms) ✓ redeem LP after fee accrual (220ms) ✓ withdraw received amounts (235ms) sell all junior to partially cover senior ✓ setup vault fixture (3943ms) ✓ create vault (1732ms) ✓ deposit senior asset (129ms) ✓ deposit junior asset (123ms) ✓ deposits as expected ✓ cannot invest too early ✓ invest assets (87ms) ✓ claim tranche tokens and excess (137ms) ✓ withdraw LP mid-duration from original deposits (198ms) ✓ deposit LP tokens mid-duration with signer 6 (347ms) ✓ deposit LP tokens mid-duration with signer 7 (345ms) ✓ withdraw LP mid-duration with signer 6 (69ms) ✓ withdraw LP mid-duration with signer 7 (68ms) ✓ redeem LP after fee accrual (189ms) ✓ withdraw received amounts (228ms) sell some junior to cover senior ✓ setup vault fixture (3465ms) ✓ create vault (1376ms) ✓ deposit senior asset (122ms) ✓ deposit junior asset (121ms) ✓ deposits as expected ✓ cannot invest too early ✓ invest assets (89ms) ✓ claim tranche tokens and excess (135ms) ✓ withdraw LP mid-duration from original deposits (208ms) ✓ deposit LP tokens mid-duration with signer 6 (335ms) ✓ deposit LP tokens mid-duration with signer 7 (349ms) ✓ withdraw LP mid-duration with signer 6 (65ms) ✓ withdraw LP mid-duration with signer 7 (66ms) ✓ redeem LP after fee accrual (204ms) ✓ withdraw received amounts (228ms) 259 passing (6m) Code Coverage Quantstamp usually recommends developers to increase the branch coverage toand above before a project goes live, in order to avoid hidden functional bugs that might not be easy to spot during the development phase. For code coverage, the current targeted files by the audit achieve poor scores that must be improved before live deployment. 90% File% Stmts% Branch% Funcs% LinesUncovered Lines contracts/85.7163.7885.0586.32 AllPairVault.sol97.4572.5597.8797.5... 1,1064,1112 OndoRegistryClient.sol100100100100 OndoRegistryClientInitializable.sol85.7162.571.4386.6747,51 Registry.sol64.295066.6765.52... 147,148,160 RolloverVault.sol74.955.8881.4876.35... 823,828,880 SampleFeeCollector.sol10050100100 TrancheToken.sol71.432563.6468.75... 101,110,119 contracts/dao/0000 GovernorBravoDelegate.sol0000... 583,584,587 GovernorBravoDelegator.sol0000... 66,67,81,83 GovernorBravoInterfaces.sol100100100100 SafeMath.sol0000... 184,203,204 Timelock.sol0000... 186,188,193 contracts/interfaces/100100100100 IBasicVault.sol100100100100 IFeeCollector.sol100100100100 IPairVault.sol100100100100 IRegistry.sol100100100100 IRollover.sol100100100100 IStrategy.sol100100100100 ITrancheToken.sol100100100100 IUserTriggeredReward.sol100100100100 IWETH.sol100100100100 contracts/libraries/100100100100 OndoLibrary.sol100100100100 contracts/strategies/80.7254.5586.0881.14 AlchemixLPStrategy.sol73.0354.357573.38... 441,473,474 BasePairLPStrategy.sol77.785010078.9585,86,87,88 SushiStakingV2Strategy.sol66.0542.1169.5766.67... 784,785,791 File% Stmts% Branch% Funcs% LinesUncovered Lines SushiStrategyLP.sol10066.67100100 UniswapStrategy.sol10078.57100100 contracts/strategies/helpers/63.64255063.64 AlchemixUserReward.sol63.64255063.6430,31,32,42 contracts/test/40.3810036.8440.38 ERC20Mock.sol40100754018,20,21 ForceSendEth.sol100100100100 IRewarder.sol100100100100 Imports.sol1001000100 MockRewarder.sol010000... 37,38,39,40 TestRewardHelper.sol01000011,15,19,20 UniPull.sol47.061005047.06... 44,45,46,47 contracts/tokens/74.8654.0583.3375.68 Ondo.sol6147.8378.2662.75... 309,312,396 StakingPools.sol91.5764.2992.3191.57... 144,259,260 contracts/vendor/abdk/10010000 ABDKMathQuad.sol10010000... 2,1664,1677 contracts/vendor/alchemix/100100100100 IStakingPools.sol100100100100 contracts/vendor/sushiswap/100100100100 IMasterChef.sol100100100100 IMasterChefV2.sol100100100100 ISushiBar.sol100100100100 contracts/vendor/uniswap/58.822562.558.82 SushiSwapLibrary.sol58.822562.558.82... 129,130,132 UniswapV2Library.sol58.822562.558.82... 129,130,132 All files70.1243.8462.3169.69 Appendix File Signatures The following are the SHA-256 hashes of the reviewed files. A file with a different SHA-256 hash has been modified, intentionally or otherwise, after the security review. You are cautioned that a different SHA-256 hash could be (but is not necessarily) an indication of a changed condition or potential vulnerability that was not within the scope of the review. Contracts 6a7f22d2234be1614b349c6eb1a5793f25209ebb12cffff9954685ee810d7c0b./strategies/SushiStakingV2Strategy.sol e98aa22663acea84b9930927eb4d5d043afdaba7ee0db2bfb93e4249f37a9040./strategies/helpers/AlchemixUserReward.sol Tests 908edcc0cb080e925404af48107fa5607cf377a86691c1d69930d845c2ed3064./test/registry.spec.ts 567a9c7e1b3987bc44df301dfe8e47c4e9c0da6417c9b9fbe41084fc202a65fb./test/alchemix.spec.ts 731ec323616913c12b4d4a053d966f1a9c7b3694346cf1cffbc4a914a6a2b214./test/staking.spec.ts 7f32b85cd16273b127afdffe45c6f7cbcfa74961af421a37aeaa79a9a68b8909./test/sushi2.spec.ts 641794a46f5826bd3f75e17ba1e88d705bb35c168cb59d94fd912b2bb04b7f84./test/ondo.spec.ts 55884a6ce789c9e7eb49d014ad5b61cb82c9342587cb8785a5e0a1ad179f17bd./test/sushi-lp.spec.ts 898f83e353c4d0408e138b8058bab776d9ea90ef2a1fc6bc4456ed6573d2497a./test/claim.spec.ts 4d4cced62f58bb967fdb051981cf30042e2feb4cbb5f036dd6d2bfdf0e5f3aaa./test/token.spec.ts 632ea85d33b6cf9f011e6e1ef462cb66c2c4965ae44ff082f5ade451ae1f1c0e./test/uni.spec.ts ffededa76363b9e27cd3a5e1feb028fd676b2f9c0b9d668c5a3fd505691cc5df./test/reverts.spec.ts 5d0def6f1d8d660ea6f3a968da264c422d4e9e5a1e84032f95cdb4129f21d757./test/rollover.spec.ts 12d8149fdc16ef1d733fb68edee18e01b1cdfe742e514208256effb1434319b3./test/vault.spec.ts 967a06267b1ed917e6976c4d0511034cc98218b77f5e6f047e896763c90c6dca./test/fee.spec.ts f53f15453e843ef9d70317f9e0b312615c3457bedb3d558fe949d82d8768f039./test/create2.spec.ts d4166571a3d52d03dec09a09bc16e9bac304f5e820da1800530a1b7e86f1f084./test/rescue.spec.ts 3555c740183d0ca7153eb1ac8f27e1ceb4110e7062a49a5a1b2bc57052abc961./test/utils/bignumberhax.ts 295e2a0d7763e85150d6eaa8bcf1779b6e5b42e760b0c1f083ce02b105d85657./test/utils/DebugSigner.ts ab65a2857c1fb33dc00d7181aac429709391d1c8e0bbc484756d14889011a696./test/utils/vault.ts 66e8bc2c94fba576664f9b3835e7622f32c416aa20b619e1e6d6b78118992477./test/utils/uni.ts 5db8a0062c5cc308c9114d7bfd4de63a940a3c0cbd0ea278e218d6f56f3aa90b./test/utils/addresses.ts 95e0919c58dd3dd10cd81597a7a034888902e174046af6e66c269077ddad8810./test/utils/signing.ts d629e629864f5062bfa441b427ad696853b1b00e644eb632fc9cc93d4d8bdecf./test/utils/getters.ts Changelog 2021-09-03 - Initial report• About Quantstamp Quantstamp is a Y Combinator-backed company that helps to secure blockchain platforms at scale using computer-aided reasoning tools, with a mission to help boost the adoption of this exponentially growing technology. With over 1000 Google scholar citations and numerous published papers, Quantstamp's team has decades of combined experience in formal verification, static analysis, and software verification. Quantstamp has also developed a protocol to help smart contract developers and projects worldwide to perform cost-effective smart contract security scans. To date, Quantstamp has protected $5B in digital asset risk from hackers and assisted dozens of blockchain projects globally through its white glove security assessment services. As an evangelist of the blockchain ecosystem, Quantstamp assists core infrastructure projects and leading community initiatives such as the Ethereum Community Fund to expedite the adoption of blockchain technology. Quantstamp's collaborations with leading academic institutions such as the National University of Singapore and MIT (Massachusetts Institute of Technology) reflect our commitment to research, development, and enabling world-class blockchain security. Timeliness of content The content contained in the report is current as of the date appearing on the report and is subject to change without notice, unless indicated otherwise by Quantstamp; however, Quantstamp does not guarantee or warrant the accuracy, timeliness, or completeness of any report you access using the internet or other means, and assumes no obligation to update any information following publication. Notice of confidentiality This report, including the content, data, and underlying methodologies, are subject to the confidentiality and feedback provisions in your agreement with Quantstamp. These materials are not to be disclosed, extracted, copied, or distributed except to the extent expressly authorized by Quantstamp. Links to other websites You may, through hypertext or other computer links, gain access to web sites operated by persons other than Quantstamp, Inc. (Quantstamp). Such hyperlinks are provided for your reference and convenience only, and are the exclusive responsibility of such web sites' owners. You agree that Quantstamp are not responsible for the content or operation of such web sites, and that Quantstamp shall have no liability to you or any other person or entity for the use of third-party web sites. Except as described below, a hyperlink from this web site to another web site does not imply or mean that Quantstamp endorses the content on that web site or the operator or operations of that site. You are solely responsible for determining the extent to which you may use any content at any other web sites to which you link from the report. Quantstamp assumes no responsibility for the use of third-party software on the website and shall have no liability whatsoever to any person or entity for the accuracy or completeness of any outcome generated by such software. Disclaimer This report is based on the scope of materials and documentation provided for a limited review at the time provided. Results may not be complete nor inclusive of all vulnerabilities. The review and this report are provided on an as-is, where-is, and as-available basis. You agree that your access and/or use, including but not limited to any associated services, products, protocols, platforms, content, and materials, will be at your sole risk. Blockchain technology remains under development and is subject to unknown risks and flaws. The review does not extend to the compiler layer, or any other areas beyond the programming language, or other programming aspects that could present security risks. A report does not indicate the endorsement of any particular project or team, nor guarantee its security. No third party should rely on the reports in any way, including for the purpose of making any decisions to buy or sell a product, service or any other asset. To the fullest extent permitted by law, we disclaim all warranties, expressed or implied, in connection with this report, its content, and the related services and products and your use thereof, including, without limitation, the implied warranties of merchantability, fitness for a particular purpose, and non-infringement. We do not warrant, endorse, guarantee, or assume responsibility for any product or service advertised or offered by a third party through the product, any open source or third-party software, code, libraries, materials, or information linked to, called by, referenced by or accessible through the report, its content, and the related services and products, any hyperlinked websites, any websites or mobile applications appearing on any advertising, and we will not be a party to or in any way be responsible for monitoring any transaction between you and any third-party providers of products or services. As with the purchase or use of a product or service through any medium or in any environment, you should use your best judgment and exercise caution where appropriate. FOR AVOIDANCE OF DOUBT, THE REPORT, ITS CONTENT, ACCESS, AND/OR USAGE THEREOF, INCLUDING ANY ASSOCIATED SERVICES OR MATERIALS, SHALL NOT BE CONSIDERED OR RELIED UPON AS ANY FORM OF FINANCIAL, INVESTMENT, TAX, LEGAL, REGULATORY, OR OTHER ADVICE. Ondo Finance V2Audit
---
# Unknown
Public SMART CONTRACT AUDIT REPORT for ONDO Prepared By:Shuxiao Wang PeckShield May 16, 2021 1/30PeckShield Audit Report #: 2021-112 Public Document Properties ClientOndo TitleSmart Contract Audit Report TargetOndo Version1.0 AuthorXuxian Jiang AuditorsYiqun Chen, Xuxian Jiang, Huaguo Shi Reviewed byShuxiao Wang Approved byXuxian Jiang ClassificationPublic Version Info VersionDateAuthor(s)Description 1.0May 16, 2021Xuxian JiangFinal Release 1.0-rc1May 10, 2021Xuxian JiangRelease Candidate #1 0.3May 3, 2021Xuxian JiangAdd More Findings #2 0.2April 30, 2021Xuxian JiangAdd More Findings #1 0.1April 26, 2021Xuxian JiangInitial Draft Contact For more information about this document and its contents, please contact PeckShield Inc. NameShuxiao Wang Phone+86 173 6454 5338 Emailcontact@peckshield.com 2/30PeckShield Audit Report #: 2021-112 Public Contents 1 Introduction4 1.1 About Ondo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 1.2 About PeckShield . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.3 Methodology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.4 Disclaimer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 2 Findings9 2.1 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 2.2 Key Findings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 3 Detailed Results11 3.1 Improved Logic in Excess Withdrawal . . . . . . . . . . . . . . . . . . . . . . . . . . 11 3.2 Duplicate Removal in Registry::tokensDeclaredDead() . . . . . . . . . . . . . . . . . 12 3.3 Explicit Input Validation in AllPairCCO::transition() . . . . . . . . . . . . . . . . . . 13 3.4 Improved Sanity Checks For System Parameters . . . . . . . . . . . . . . . . . . . . 14 3.5 Incorrect Performance Fee Calculation . . . . . . . . . . . . . . . . . . . . . . . . . 16 3.6 Redundant Code Removal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 3.7 Accommodation of approve() Idiosyncrasies . . . . . . . . . . . . . . . . . . . . . . 18 3.8 Trust Issue of Admin Keys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 3.9 Possible Front-Running For Reduced Return . . . . . . . . . . . . . . . . . . . . . . 21 3.10 Improved Business Logic in RolloverCCO::deposit() . . . . . . . . . . . . . . . . . . 23 3.11 Potentially Repeated Excess Returns Of RolloverCCO . . . . . . . . . . . . . . . . . 24 4 Conclusion28 References29 3/30PeckShield Audit Report #: 2021-112 Public 1 | Introduction Given the opportunity to review theOndodesign document and related smart contract source code, we outline in the report our systematic approach to evaluate potential security issues in the smart contract implementation, expose possible semantic inconsistencies between smart contract code and design document, and provide additional suggestions or recommendations for improvement. Our results show that the given version of smart contracts can be further improved due to the presence of several issues related to either security or performance. This document outlines our audit results. 1.1 About Ondo The goal of Ondo is to allow investors to shift the risk and reward balance between each other. In par- ticular, Ondo classifies investors into two groups: theseniorandjunior tranche. Thesenior tranche will receive a fixed percentage over their initial investments. Thejunior tranchewill receive any excess returns over the senior tranche. This fixed percentage, called thehurdle rate, is determined when the product is created. The underlying investment is liquidity provider tokens on decentralized exchanges, e.g.Uniswap,Sushiswap,Balancer,Curve, etc. Liquidity providers inject an equal value of a pair of assets into a liquidity pool. In return they earn fees and incentives for providing liquidity, which is collected by withdrawing liquidity from the pool. The basic information of Ondo is as follows: Table 1.1: Basic Information of Ondo ItemDescription IssuerOndo TypeEthereum Smart Contract PlatformSolidity Audit MethodWhitebox Latest Audit ReportMay 16, 2021 In the following, we show the Git repository of reviewed files and the commit hash value used 4/30PeckShield Audit Report #: 2021-112 Public in this audit. Note that Ondo assumes a trusted price oracle with timely market price feeds for supported assets and the oracle itself is not part of this audit. • https://github.com/ondoprotocol/protocol-audit.git (29b2c9a) 1.2 About PeckShield PeckShield Inc. \[10\] is a leading blockchain security company with the goal of elevating the secu- rity, privacy, and usability of current blockchain ecosystems by offering top-notch, industry-leading services and products (including the service of smart contract auditing). We are reachable at Telegram ( https://t.me/peckshield), Twitter (http://twitter.com/peckshield), or Email (contact@peckshield.com). Table 1.2: Vulnerability Severity Classification Impact HighCriticalHighMedium MediumHighMediumLow LowMediumLowLow HighMediumLow Likelihood 1.3 Methodology To standardize the evaluation, we define the following terminology based on the OWASP Risk Rating Methodology \[9\]: • Likelihood represents how likely a particular vulnerability is to be uncovered and exploited in the wild; • Impact measures the technical loss and business damage of a successful attack; •Severity demonstrates the overall criticality of the risk. Likelihood and impact are categorized into three ratings:H,MandL, i.e.,high,mediumand lowrespectively. Severity is determined by likelihood and impact and can be classified into four categories accordingly, i.e.,Critical,High,Medium,Lowshown in Table 1.2. 5/30PeckShield Audit Report #: 2021-112 Public Table 1.3: The Full Audit Checklist CategoryChecklist Items Basic Coding Bugs Constructor Mismatch Ownership Takeover Redundant Fallback Function Overflows & Underflows Reentrancy Money-Giving Bug Blackhole Unauthorized Self-Destruct Revert DoS Unchecked External Call Gasless Send Send Instead Of Transfer Costly Loop (Unsafe) Use Of Untrusted Libraries (Unsafe) Use Of Predictable Variables Transaction Ordering Dependence Deprecated Uses Semantic Consistency ChecksSemantic Consistency Checks Advanced DeFi Scrutiny Business Logics Review Functionality Checks Authentication Management Access Control & Authorization Oracle Security Digital Asset Escrow Kill-Switch Mechanism Operation Trails & Event Generation ERC20 Idiosyncrasies Handling Frontend-Contract Integration Deployment Consistency Holistic Risk Management Additional Recommendations Avoiding Use of Variadic Byte Array Using Fixed Compiler Version Making Visibility Level Explicit Making Type Inference Explicit Adhering To Function Declaration Strictly Following Other Best Practices 6/30PeckShield Audit Report #: 2021-112 Public To evaluate the risk, we go through a checklist of items and each would be labeled with a severity category. For one check item, if our tool or analysis does not identify any issue, the contract is considered safe regarding the check item. For any discovered issue, we might further deploy contracts on our private testnet and run tests to confirm the findings. If necessary, we would additionally build a PoC to demonstrate the possibility of exploitation. The concrete list of check items is shown in Table 1.3. In particular, we perform the audit according to the following procedure: • BasicCodingBugs: We first statically analyze given smart contracts with our proprietary static code analyzer for known coding bugs, and then manually verify (reject or confirm) all the issues found by our tool. • SemanticConsistencyChecks: We then manually check the logic of implemented smart con- tracts and compare with the description in the white paper. • AdvancedDeFiScrutiny: We further review business logics, examine system operations, and place DeFi-related aspects under scrutiny to uncover possible pitfalls and/or bugs. • AdditionalRecommendations: We also provide additional suggestions regarding the coding and development of smart contracts from the perspective of proven programming practices. To better describe each issue we identified, we categorize the findings with Common Weakness Enumeration (CWE-699) \[8\], which is a community-developed list of software weakness types to better delineate and organize weaknesses around concepts frequently encountered in software devel- opment. Though some categories used in CWE-699 may not be relevant in smart contracts, we use the CWE categories in Table 1.4 to classify our findings. Moreover, in case there is an issue that may affect an active protocol that has been deployed, the public version of this report may omit such issue, but will be amended with full details right after the affected protocol is upgraded with respective fixes. 1.4 Disclaimer Note that this security audit is not designed to replace functional tests required before any software release, and does not give any warranties on finding all possible security issues of the given smart contract(s) or blockchain software, i.e., the evaluation result does not guarantee the nonexistence of any further findings of security issues. As one audit-based assessment cannot be considered comprehensive, we always recommend proceeding with several independent audits and a public bug bounty program to ensure the security of smart contract(s). Last but not least, this security audit should not be used as investment advice. 7/30PeckShield Audit Report #: 2021-112 Public Table 1.4: Common Weakness Enumeration (CWE) Classifications Used in This Audit CategorySummary ConfigurationWeaknesses in this category are typically introduced during the configuration of the software. Data Processing IssuesWeaknesses in this category are typically found in functional- ity that processes data. Numeric ErrorsWeaknesses in this category are related to improper calcula- tion or conversion of numbers. Security FeaturesWeaknesses in this category are concerned with topics like authentication, access control, confidentiality, cryptography, and privilege management. (Software security is not security software.) Time and StateWeaknesses in this category are related to the improper man- agement of time and state in an environment that supports simultaneous or near-simultaneous computation by multiple systems, processes, or threads. Error Conditions, Return Values, Status Codes Weaknesses in this category include weaknesses that occur if a function does not generate the correct return/status code, or if the application does not handle all possible return/status codes that could be generated by a function. Resource ManagementWeaknesses in this category are related to improper manage- ment of system resources. Behavioral IssuesWeaknesses in this category are related to unexpected behav- iors from code that an application uses. Business LogicWeaknesses in this category identify some of the underlying problems that commonly allow attackers to manipulate the business logic of an application. Errors in business logic can be devastating to an entire application. Initialization and CleanupWeaknesses in this category occur in behaviors that are used for initialization and breakdown. Arguments and ParametersWeaknesses in this category are related to improper use of arguments or parameters within function calls. Expression IssuesWeaknesses in this category are related to incorrectly written expressions within code. Coding PracticesWeaknesses in this category are related to coding practices that are deemed unsafe and increase the chances that an ex- ploitable vulnerability will be present in the application. They may not directly introduce a vulnerability, but indicate the product has not been carefully developed or maintained. 8/30PeckShield Audit Report #: 2021-112 Public 2 | Findings 2.1 Summary Here is a summary of our findings after analyzing the implementation of the Ondo protocol. During the first phase of our audit, we study the smart contract source code and run our in-house static code analyzer through the codebase. The purpose here is to statically identify known coding bugs, and then manually verify (reject or confirm) issues reported by our tool. We further manually review business logic, examine system operations, and place DeFi-related aspects under scrutiny to uncover possible pitfalls and/or bugs. Severity# of Findings Critical0 High1 Medium5 Low5 Informational0 Total11 We have so far identified a list of potential issues: some of them involve subtle corner cases that might not be previously thought of, while others refer to unusual interactions among multiple contracts. For each uncovered issue, we have therefore developed test cases for reasoning, reproduction, and/or verification. After further analysis and internal discussion, we determined a few issues of varying severities need to be brought up and paid more attention to, which are categorized in the above table. More information can be found in the next subsection, and the detailed discussions of each of them are in Section 3. 9/30PeckShield Audit Report #: 2021-112 Public 2.2 Key Findings Overall, these smart contracts are well-designed and engineered, though the implementation can be improved by resolving the identified issues (shown in Table 2.1), including1high-severity vulnerability, 5medium-severity vulnerabilities, and5low-severity vulnerabilities. Table 2.1: Key Ondo Audit Findings IDSeverityTitleCategoryStatus PVE-001MediumImproved Logic in Excess WithdrawalSecurity FeaturesFixed PVE-002LowDuplicateRemovalinReg- istry::tokensDeclaredDead() Business LogicFixed PVE-003LowExplicit Input Validation in AllPair- CCO::transition() Business LogicFixed PVE-004LowImproved Sanity Checks Of System/- Function Parameters Coding PracticesFixed PVE-005MediumIncorrect Performance Fee CalculationBusiness LogicConfirmed PVE-006LowRedundant Code RemovalCoding PracticesFixed PVE-007LowAccommodation of approve() Idiosyn- crasies Coding PracticesFixed PVE-008MediumTrust Issue of Admin KeysSecurity FeaturesConfirmed PVE-009MediumPossible Front-Running For Reduced Re- turn Business LogicFixed PVE-010HighImproved Business Logic in Rollover- CCO::deposit() Business LogicFixed PVE-011MediumPotentially Repeated Excess Returns Of RolloverCCO Business LogicResolved Beside the identified issues, we emphasize that for any user-facing applications and services, it is always important to develop necessary risk-control mechanisms and make contingency plans, which may need to be exercised before the mainnet deployment. The risk-control mechanisms should kick in at the very moment when the contracts are being deployed on mainnet. Please refer to Section 3 for details. 10/30PeckShield Audit Report #: 2021-112 Public 3 | Detailed Results 3.1 Improved Logic in Excess Withdrawal •ID: PVE-001 •Severity: Medium •Likelihood: Low •Impact: High •Target:BasePairLPStrategy •Category: Security Features \[5\] •CWE subcategory: CWE-287 \[2\] Description TheOndoprotocol has a number of essential contracts for different functionalities and duties: strategies,AllPairCCO,RolloverCCO,Registry, andTrancheToken. While examining theBasePairLPStrategy contract, we notice one public functionwithdrawExcess()is not properly guarded. To elaborate, we show below thewithdrawExcess()routine that is designed to transfer any unused deposits back to the investor. We notice that the current logic employs theisAuthorized(OLib. CCO\_ROLE)modifier to requireCCO\_ROLEauthorization. However, the proper authorization should be more explicit, i.e.,onlyOrigin(\_ccoId). By doing so, only the origin of the intended\_ccoIDmay able to request the return of excess tokens, not any account with theCCO\_ROLEauthorization. 87/\*\* 88\* @notice Send excess tokens to investor 89\*/ 90f u n c t i o nwithdrawExcess ( 91u i n t 2 5 6\_ccoId , 92OLib . Tranche tranche , 93a d d r e s sto , 94u i n t 2 5 6amount 95)e x t e r n a lo v e r r i d e i s A u t h o r i z e d ( OLib .CCO\_ROLE) { 96CCOs t o r a g e\_cco = ccos \[ \_ccoId \] ; 97i f( tranche == OLib . Tranche . Senior ) { 98u i n t 2 5 6excess = \_cco . s e n i o r E x c e s s ; 99r e q u i r e( amount <= excess ,"Withdrawing too much") ; 100\_cco . s e n i o r E x c e s s−= amount ; 101\_cco . s e n i o r . s a f e T r a n s f e r ( to , amount ) ; 11/30PeckShield Audit Report #: 2021-112 Public 102}e l s e{ 103u i n t 2 5 6excess = \_cco . j u n i o r E x c e s s ; 104r e q u i r e( amount <= excess ,"Withdrawing too much") ; 105\_cco . j u n i o r E x c e s s−= amount ; 106\_cco . j u n i o r . s a f e T r a n s f e r ( to , amount ) ; 107} 108} Listing 3.1:BasePairLPStrategy::withdrawExcess() RecommendationAuthenticate the caller ofwithdrawExcess()to beonlyOrigin(\_ccoId), not the currentisAuthorized(OLib.CCO\_ROLE). StatusThis issue has been fixed in this commit:1e9db80. 3.2 Duplicate Removal in Registry::tokensDeclaredDead() •ID: PVE-002 •Severity: Low •Likelihood: Low •Impact: Low •Target:Registry •Category: Business Logic \[7\] •CWE subcategory: CWE-841 \[4\] Description TheOndoprotocol has a protocol-wide registryRegistrywith a number of access control-related configurations. Our analysis shows that the contract also maintains an internal list ofTrancheToken instances that can be recycled for gas efficiency. To elaborate, we show below the responsibletokensDeclaredDead()routine. As the name indicates, this routine adds the given list of tokens into an internal arraydeadTokenswhere the governance can delete to save gas. However, it comes to our attention that the given list is not validated for any duplicate. 88/\*\* 89\* @notice Manually determine which TrancheToken instances can be recycled 90\* @dev Move into another list where createCCO can delete to save gas. Done manually for safety. 91\* @param \_tokens List of tokens 92\*/ 93f u n c t i o ntokensDeclaredDead (a d d r e s s\[ \] c a l l d a t a \_tokens ) 94e x t e r n a l 95onlyGovernance 96{ 97f o r(u i n t 2 5 6i = 0; i < \_tokens .l e n g t h; i++) { 98deadTokens .push( ITrancheToken ( \_tokens \[ i \] ) ) ; 99} 12/30PeckShield Audit Report #: 2021-112 Public 100} Listing 3.2:Registry :: tokensDeclaredDead() RecommendationRevise thetokensDeclaredDead()logic to not save into the internal array deadTokenswith duplicates StatusThis issue has been fixed in this commit:2156b55. 3.3 Explicit Input Validation in AllPairCCO::transition() •ID: PVE-003 •Severity: Low •Likelihood: Low •Impact: Low •Target:AllPairCCO •Category: Business Logic \[7\] •CWE subcategory: CWE-841 \[4\] Description In theOndoprotocol, there is a coreAllPairCCOcontract that contains most of the implementation forCollateralized Crypto Obligations (CCO)s. Specifically, rather than creating unique contract in- stances for eachCCO, the state for allCCOsis stored in a mapping. EachCCOhas a unique id number created by hashing the metadata on theCCO:asset pair,strategy contract,start time,investment time, andduration. EachCCOhas to be one of four self-evident states:Inactive,Deposit,Live, and Withdraw. In order to facilitate the (linear) state transition among these four states, a helper routine transition()is provided. To elaborate, we show below thetransition()helper routine. Our analysis shows one specific transitionLive -> Withdrawcan be improved by explicitly enforcing the required states. In particu- lar, the current logic only enforcesrequire(curState == OLib.State.Live)(line120), which can be improved asrequire(curState == OLib.State.Live && \_nextState == OLib.State.Withdraw ). 106// Determine if one can move to a new state. For now the transitions 107// are strictly linear. No state machines , really. 108m o d i f i e rt r a n s i t i o n (u i n t 2 5 6\_ccoId , OLib . State \_nextState ) { 109CCOs t o r a g ecco\_ = CCOs \[ \_ccoId \] ; 110OLib . State curState = cco\_ . s t a t e ; 111i f( \_nextState == OLib . State . Live ) { 112r e q u i r e( 113curState == OLib . State . Deposit , 114// "Cannot transition to Live from current state" 115i n v a l i d T r a n s i t i o n M s g 116) ; 117r e q u i r e( cco\_ . i n v e s t A t <=b l o c k.timestamp,"Not yet time to invest") ; 118}e l s e{ 13/30PeckShield Audit Report #: 2021-112 Public 119r e q u i r e( 120curState == OLib . State . Live , 121// "Cannot transition to Withdraw from current state" 122i n v a l i d T r a n s i t i o n M s g 123) ; 124r e q u i r e( cco\_ . redeemAt <=b l o c k.timestamp,"Not yet time to redeem") ; 125} 126cco\_ . s t a t e = \_nextState ; 127CCOsByState \[ curState \] . remove ( \_ccoId ) ; 128CCOsByState \[ \_nextState \] . add ( \_ccoId ) ; 129\_; 130} Listing 3.3:AllPairCCO:: transition () RecommendationProperly strengthen thetransition()logic by making state transition ex- plicit. StatusThis issue has been fixed in this commit:7e82cf9. 3.4 Improved Sanity Checks For System Parameters •ID: PVE-004 •Severity: Low •Likelihood: Low •Impact: Low •Target:Multiple Contracts •Category: Coding Practices \[6\] •CWE subcategory: CWE-1126 \[1\] Description DeFi protocols typically have a number of system-wide parameters that can be dynamically configured on demand. TheOndoprotocol is no exception. In the following, we examine a number of routines that can be improved to better validate the given input. The first routineAllPairCCO::maybeOpenDeposit()determines whether a givenCCOcan shift to an open state. Besides the current validation, it is better to add the following requirement, i.e., require(cco\_.startAt > 0 && cco\_.startAt <= block.timestamp), to ensure thestartAtfield is indeed valid. 132// Determine if a CCO can shift to an open state. A CCO is started 133// in an inactive state. It can only move forward when time has 134// moved past the starttime. 135m o d i f i e rmaybeOpenDeposit (u i n t 2 5 6\_ccoId ) { 136CCOs t o r a g ecco\_ = CCOs \[ \_ccoId \] ; 137i f( cco\_ . s t a t e == OLib . State . I n a c t i v e ) { 138r e q u i r e( cco\_ . s t a r t A t <=b l o c k.timestamp,"Not yet time to enroll") ; 14/30PeckShield Audit Report #: 2021-112 Public 139cco\_ . s t a t e = OLib . State . Deposit ; 140CCOsByState \[ OLib . State . I n a c t i v e \] . remove ( \_ccoId ) ; 141CCOsByState \[ OLib . State . Deposit \] . add ( \_ccoId ) ; 142}e l s e i f( cco\_ . s t a t e != OLib . State . Deposit ) { 143r e v e r t("Invalid operation at current state") ; 144} 145\_; 146} Listing 3.4:AllPairCCO::maybeOpenDeposit() The second routinecanDeposit()determines whether the givenCCOcan accept investor de- posits. This routine can be similarly improved by verifyingcco\_.startAt > 0 && cco\_.startAt <= block.timestamp. 906f u n c t i o ncanDeposit (u i n t 2 5 6\_ccoId )e x t e r n a l v i e wo v e r r i d er e t u r n s(b o o l) { 907CCOs t o r a g ecco\_ = CCOs \[ \_ccoId \] ; 908i f( cco\_ . s t a t e == OLib . State . I n a c t i v e ) { 909r e t u r ncco\_ . s t a r t A t <=b l o c k.timestamp; 910} 911r e t u r ncco\_ . s t a t e == OLib . State . Deposit ; 912} Listing 3.5:AllPairCCO::canDeposit() The third routinecreateAndAddNextCco()defines the nextCCOfor this rollover to invest. It is suggested to perform a more through validation on the given\_ccoParamsto define aCCO. 353f u n c t i o ncreateAndAddNextCco ( 354u i n t 2 5 6\_ r o l l o v e r I d , 355OLib . CCOParamsmemory\_ccoParams 356) 357e x t e r n a l 358noPanic 359notDead ( \_ r o l l o v e r I d ) 360onlyCreator ( \_ r o l l o v e r I d ) 361nonReentrant 362{ 363R o l l o v e rs t o r a g er o l l o v e r \_ = r o l l o v e r s \[ \_ r o l l o v e r I d \] ; 364\_ccoParams . startTime = 365ccoManager . redeemAt ( r o l l o v e r \_ . rounds \[ r o l l o v e r \_ . thisRound + 1 \] . ccoId )− 366\_ccoParams . enrollment ; 367u i n t 2 5 6newCcoId = ccoManager . createCCO ( \_ccoParams ) ; 368\_addNextCco ( \_ r o l l o v e r I d , newCcoId ) ; 369} Listing 3.6:RolloverCCO::createAndAddNextCco() RecommendationValidate any untrusted input before it can be accepted for normal processing. Also, guard any changes on the system-wide parameters to ensure they fall in an appropriate range. Also, consider emitting related events for external monitoring and analytics tools. 15/30PeckShield Audit Report #: 2021-112 Public StatusThis issue has been fixed in the following commits:d1d14e5, 8477b11, e802dea,and 8f96dbb. 3.5 Incorrect Performance Fee Calculation •ID: PVE-005 •Severity: Low •Likelihood: Medium •Impact: Low •Target:AllPairCCO •Category: Business Logic \[7\] •CWE subcategory: CWE-841 \[4\] Description As mentioned earlier, theOndoprotocol allows investors to shift the risk and reward balance between each other. Currently, the protocol supports two types of investors: thesenior trancheandjunior tranche. Thesenior tranchewill receive a fixed percentage over their initial investments. The junior tranchewill receive any excess returns over thesenior tranche. This fixed percentage, called thehurdle rate, is determined when the product is created. In particular, we show below theAllPairCCO::takePerformanceFee()routine that is used to cal- culate the performance fee for the strategist. It comes to our attention that the calculated fee is currently based on received amount byjunior tranche, instead of the earned amount after the hurdle ratereduction. As a result, thesenior tranchemay not get the expectedhurdle rate. 789f u n c t i o ntakePerformanceFee (CCOs t o r a g ecco )i n t e r n a l r e t u r n s(u i n t 2 5 6f e e ) { 790f e e = 0; 791i f( performanceFeeCollector !=a d d r e s s(0) ) { 792Assets t o r a g ej u n i o r = cco . a s s e t s \[ OLib . Tranche . Junior \] ; 793u i n t 2 5 6j u n i o r H u r d l e = 794j u n i o r 795. t o t a l I n v e s t e d 796. fromUInt () 797. mul (( denominator + cco . hurdleRate ) . fromUInt () ) 798. div ( denominator . fromUInt () ) 799. toUInt () ; 801i f( j u n i o r . r e c e i v e d > j u n i o r H u r d l e ) { 802f e e = cco 803. performanceFee 804. fromUInt () 805. mul ( j u n i o r . r e c e i v e d . fromUInt () ) 806. div ( denominator . fromUInt () ) 807. toUInt () ; 808IERC20 ( j u n i o r . token ) . safeTransferFrom ( 809a d d r e s s( cco . s t r a t e g y ) , 810performanceFeeCollector , 16/30PeckShield Audit Report #: 2021-112 Public 811f e e 812) ; 813} 814} 815} Listing 3.7:AllPairCCO::takePerformanceFee() RecommendationRevise the above calculations to ensure thesenior tranchecan get the expectedhurdle rate. StatusThis issue has been confirmed. 3.6 Redundant Code Removal •ID: PVE-006 •Severity: Low •Likelihood: Low •Impact: Low •Target:Multiple Contracts •Category: Coding Practices \[6\] •CWE subcategory: CWE-563 \[3\] Description TheOndoprotocol makes good use of a number of reference contracts, such asERC20,SafeERC20, SafeMath, andAccessControl, to facilitate its code implementation and organization. For example, theAllPairCCOsmart contract has so far imported at least five reference contracts. However, we observe the inclusion of certain unused code or the presence of unnecessary redundancies that can be safely removed. For example, if we examine closely theUniswapStrategy::constructor()routine, it contains the repeated initialization ofregistry(line35). 30c o n s t r u c t o r( 31a d d r e s s\_registry , 32a d d r e s s\_router , 33a d d r e s s\_factory 34) BasePairLPStrategy ( \_ r e g i s t r y ) { 35r e g i s t r y = R e g i s t r y ( \_ r e g i s t r y ) ; 36uniRouter02 = IUniswapV2Router02 ( \_router ) ; 37uniFactory = \_factory ; 38} Listing 3.8:UniswapStrategy::constructor() In addition, theupdatePool()routine can be revised as the requirement onrequire(token0 != address(sushiToken)|| token1 != address(sushiToken))is always true – as it is impossible to have a pool with the sametoken0andtoken1. 17/30PeckShield Audit Report #: 2021-112 Public 247f u n c t i o nupdatePool (a d d r e s s\_pool ,a d d r e s s\[ \] c a l l d a t a pathFromSushi ) 248e x t e r n a l 249nonReentrant 250noPanic 251i s A u t h o r i z e d ( OLib .STRATEGIST\_ROLE) 252{ 253r e q u i r e( pools \[ \_pool \] . \_isSet ,"Pool ID not yet registered") ; 254a d d r e s stoken0 = IUniswapV2Pair ( \_pool ) . token0 () ; 255a d d r e s stoken1 = IUniswapV2Pair ( \_pool ) . token1 () ; 256r e q u i r e( 257token0 !=a d d r e s s( sushiToken ) token1 !=a d d r e s s( sushiToken ) , 258"Should never need to update pool with sushi token" 259) ; 260a d d r e s sendToken = pathFromSushi \[ pathFromSushi .l e n g t h−1 \] ; 261r e q u i r e( 262IUniswapV2Pair ( \_pool ) . token0 () == endToken 263IUniswapV2Pair ( \_pool ) . token1 () == endToken , 264"Not a valid path for pool" 265) ; 266PoolDatas t o r a g epoolData = pools \[ \_pool \] ; 267d e l e t epoolData . pathFromSushi ; 268pools \[ \_pool \] . pathFromSushi = pathFromSushi ; 269} Listing 3.9:SushiStrategyLP::updatePool() Similarly, if we examine theAllPairCCO::depositFromRollover()routine, the internal require- mentaddress(cco\_.rollover)== msg.sender(line441) is redundant as it is already guaranteed by theonlyRollover(\_ccoId, \_rolloverId)modifier. RecommendationConsider the removal of the redundant code in above routines. StatusThis issue has been fixed in the following commits:1d53499, fcc8a89,and055bb88. 3.7 Accommodation of approve() Idiosyncrasies •ID: PVE-007 •Severity: Low •Likelihood: Low •Impact: Low •Target:Multiple Contracts •Category: Coding Practices \[6\] •CWE subcategory: CWE-1126 \[1\] Description Though there is a standardized ERC-20 specification, many token contracts may not strictly follow the specification or have additional functionalities beyond the specification. In this section, we examine theapprove()routine and analyze possible idiosyncrasies from current widely-used token contracts. 18/30PeckShield Audit Report #: 2021-112 Public In particular, we use the popular stablecoin, i.e.,USDT, as our example. We show the related code snippet below. On its entry ofapprove(), there is a requirement, i.e.,require(!((\_value != 0) && (allowed\[msg.sender\]\[\_spender\] != 0))). This specific requirement essentially indicates the need of reducing the allowance to0first (by callingapprove(\_spender, 0)) if it is not, and then calling a second one to set the proper allowance. This requirement is in place to mitigate the knownapprove()/ transferFrom()race condition (https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729). 194/\*\* 195\* @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender. 196\* @param \_spender The address which will spend the funds. 197\* @param \_value The amount of tokens to be spent. 198\*/ 199f u n c t i o napprove (a d d r e s s\_spender ,u i n t\_value )p u b l i conlyPayloadSize (2∗32) { 201// To change the approve amount you first have to reduce the addresses ‘ 202// allowance to zero by calling ‘approve(\_spender , 0)‘ if it is not 203// already 0 to mitigate the race condition described here: 204// https :// github.com/ethereum/EIPs/issues /20# issuecomment -263524729 205r e q u i r e( ! ( ( \_value != 0) && ( allowed \[msg.s e n d e r\] \[ \_spender \] != 0) ) ) ; 207allowed \[msg.s e n d e r\] \[ \_spender \] = \_value ; 208Approval (msg.s e n d e r, \_spender , \_value ) ; 209} Listing 3.10:USDT TokenContract Because of that, a normal call toapprove()with a currently non-zero allowance may fail. In the following, we use theSushiStrategyLP::addLiquidity()routine as an example. This routine is designed to approve a specific token for swap contract. To accommodate the specific idiosyncrasy, for eachsafeIncreaseAllowance(), there is a need toapprove()twice (lines445 − 446): the first one reduces the allowance to0; and the second one sets the new allowance. 440f u n c t i o na d d L i q u i d i t y ( 441a d d r e s stoken0 , 442a d d r e s stoken1 , 443u i n t 2 5 6amt0 , 444u i n t 2 5 6amt1 , 445u i n t 2 5 6minOut0 , 446u i n t 2 5 6minOut1 447) 448i n t e r n a l 449r e t u r n s( 450u i n t 2 5 6out0 , 451u i n t 2 5 6out1 , 452u i n t 2 5 6lp 453) 454{ 455IERC20 ( token0 ) . s a f e I n c r e a s e A l l o w a n c e (a d d r e s s( sushiRouter ) , amt0 ) ; 456IERC20 ( token1 ) . s a f e I n c r e a s e A l l o w a n c e (a d d r e s s( sushiRouter ) , amt1 ) ; 19/30PeckShield Audit Report #: 2021-112 Public 457( out0 , out1 , lp ) = sushiRouter . a d d L i q u i d i t y ( 458token0 , 459token1 , 460amt0 , 461amt1 , 462minOut0 , 463minOut1 , 464a d d r e s s(t h i s) , 465b l o c k.timestamp 466) ; 467} Listing 3.11:SushiStrategyLP:: addLiquidity () Moreover, it is important to note that for certain non-compliant ERC20 tokens (e.g., USDT), thetransfer()function does not have a return value. However, theIERC20interface has defined the transfer()interface with aboolreturn value. As a result, the call totransfer()may expect a return value. With the lack of return value ofUSDT’stransfer(), the call will be unfortunately reverted. Because of that, a normal call totransfer()is suggested to use the safe version, i.e.,safeTransfer (), In essence, it is a wrapper around ERC20 operations that may either throw on failure or return false without reverts. Moreover, the safe version also supports tokens that return no value (and instead revert or throw on failure). Note that non-reverting calls are assumed to be successful. To use this library you can add a using SafeERC20 for IERC20. Similarly, there is a safe version of approve()/transferFrom()as well, i.e.,safeApprove()/safeTransferFrom(). RecommendationAccommodate the above-mentioned idiosyncrasy about ERC20-related approve()/transfer()/transferFrom(). StatusThis issue has been fixed in this commit:074dd9b. 3.8 Trust Issue of Admin Keys •ID: PVE-008 •Severity: Medium •Likelihood: Medium •Impact: Medium •Target:Multiple Contracts •Category: Security Features \[5\] •CWE subcategory: CWE-287 \[2\] Description In theOndoprotocol, there is a special administrative accountgovwithGOVERNANCE\_ROLE. Thisgov account plays a critical role in governing and regulating the system-wide operations (e.g., assign various roles, specify the swap path, and set rollovers). It also has the privilege to regulate or 20/30PeckShield Audit Report #: 2021-112 Public govern the flow of assets among the involved components in the protocol. And the presence of an administrative account can allow for emergency operations. We emphasize that current privilege assignment is necessary and required for proper protocol operation. However, it is worrisome if thegovis not governed by aDAO-like structure. The discussion with the team has confirmed that thegovwill be managed by a multi-sig account. Note that a compromisedgovaccount is capable of modifying current protocol configuaration with adverse consequences on user funds. RecommendationPromptly transfer thegovprivilege to the intendedDAO-like governance contract. StatusThis issue has been confirmed. 3.9 Possible Front-Running For Reduced Return •ID: PVE-009 •Severity: Medium •Likelihood: Medium •Impact: Medium •Target:Multiple Contracts •Category: Business Logic \[7\] •CWE subcategory: CWE-841 \[4\] Description In theOndoprotocol, there is aSushiStrategyLPstrategy that has an additional methodharvest() to occasionally convert earnedSushiinto a balance ofseniorandjuniorassets to reinvest into LP tokens, which are then placed intoMasterchefto earnSushi To elaborate, we show below theSushiStrategyLP::harvest()routine. This routine delegates the call to an internal\_compound()handler to reinvestsushi/xsushiinto LP tokens. 352/\*\* 353\* @notice Periodically reinvest sushi/xsushi into LP tokens 354\* @param pool Sushiswap pool to reinvest 355\*/ 356f u n c t i o nh a r v e s t (a d d r e s spool )e x t e r n a li s A u t h o r i z e d ( OLib .STRATEGIST\_ROLE) { 357PoolDatas t o r a g epoolData = pools \[ pool \] ; 358\_compound( IERC20 ( pool ) , poolData ) ; 359} Listing 3.12:SushiStrategyLP:: harvest () 277f u n c t i o n\_compound( IERC20 pool , PoolDatas t o r a g epoolData )i n t e r n a l{ 278u i n t 2 5 6sushiAmt = sushiToken . balanceOf (a d d r e s s(t h i s) ) ; 279masterChef . d e p o s i t ( poolData . pid , 0) ;// Called to trigger update in amount of sushi truly available now 21/30PeckShield Audit Report #: 2021-112 Public 280xSushi . l e a v e ( poolData . pendingXSushi ) ; 281poolData . pendingXSushi = 0; 282sushiAmt = sushiToken . balanceOf (a d d r e s s(t h i s) )−sushiAmt ; 283i f( sushiAmt > 0) { 284a d d r e s s\[ \]memorypathFromSushi = getSushiPath ( poolData . pathFromSushi ) ; 285a d d r e s stokenA = pathFromSushi \[ pathFromSushi .l e n g t h−1 \] ; 286a d d r e s stokenB = IUniswapV2Pair (a d d r e s s( pool ) ) . token0 () ; 287i f( tokenB == tokenA ) tokenB = IUniswapV2Pair (a d d r e s s( pool ) ) . token1 () ; 288u i n t 2 5 6amt0 ; 289i f( tokenA ==a d d r e s s( sushiToken ) ) { 290amt0 = sushiAmt ; 291}e l s e{ 292amt0 = swapExactIn ( sushiAmt , 0 , pathFromSushi ) ; 293} 294u i n t 2 5 6amt0ToSwap ; 295(u i n t 2 5 6r e s e r v es 0 , ) = 296SushiSwapLibrary . getReserves ( sushiFactory , tokenA , tokenB ) ; 297amt0−= (amt0ToSwap = calculateSwapInAmount ( r e s e r v e s 0 , amt0 ) ) ; 298u i n t 2 5 6amt1 = swapExactIn (amt0ToSwap , 0 , getPath ( tokenA , tokenB ) ) ; 299( , ,u i n t 2 5 6lpAmt ) = a d d L i q u i d i t y ( tokenA , tokenB , amt0 , amt1 , 0 , 0) ; 300// TODO: do something with excess - will be extremely minimal though (<2) 301poolData . totalLp += lpAmt ; 302} 303pool . s a f e I n c r e a s e A l l o w a n c e ( 304a d d r e s s( masterChef ) , 305pool . balanceOf (a d d r e s s(t h i s) ) 306) ; 307masterChef . d e p o s i t ( poolData . pid , pool . balanceOf (a d d r e s s(t h i s) ) ) ; 308} Listing 3.13:SushiStrategyLP::\_compound() We notice the conversion is routed toSushiswapin order to swap one token to another for liquidity addition. And the swap operation does not specify any restriction on possible slippage and is therefore vulnerable to possible front-running attacks, resulting in a smaller gain for this round of yielding. Note that this is a common issue plaguing current AMM-based DEX solutions. Specifically, a large trade may be sandwiched by a preceding sell to reduce the market price, and a tailgating buy- back of the same amount plus the trade amount. Such sandwiching behavior unfortunately causes a loss and brings a smaller return as expected to the trading user or thestrategycontract in our case because the swap rate is lowered by the preceding sell. As a mitigation, we may consider specifying the restriction on possible slippage caused by the trade or referencing theTWAPortime-weighted average priceofUniswapV2. Nevertheless, we need to acknowledge that this is largely inherent to current blockchain infrastructure and there is still a need to continue the search efforts for an effective defense. RecommendationDevelop an effective mitigation to the above front-running attack to better protect the interests of farming users. 22/30PeckShield Audit Report #: 2021-112 Public StatusThis issue has been fixed in this commit:6b7f856. 3.10 Improved Business Logic in RolloverCCO::deposit() •ID: PVE-010 •Severity: High •Likelihood: Medium •Impact: High •Target:RolloverCCO •Category: Business Logic \[7\] •CWE subcategory: CWE-841 \[4\] Description TheOndoprotocol also supportsRolloverCCOthat can automate the investment process by investing in a series of similar CCOs. Investors can deposit money into theRolloverCCO, get a token to represent their stake, and redeem it later to collect their investment plus profits (or losses). In the following, we examine the deposit logic. To elaborate, we useRolloverCCO::deposit()routine. The logic is rather straightforward in allowing investors to deposit tokens into a queue to get invested in the nextCCO. However, it comes to our attention that when there is an excess and the excess is more than the deposited amount for investment, there is a need to reset\_amount = 0. The reset operation is missing in current logic, resulting in possible loss for the depositing user. 437f u n c t i o nd e p o s i t ( 438u i n t 2 5 6\_ r o l l o v e r I d , 439OLib . Tranche \_tranche , 440u i n t 2 5 6\_amount 441)e x t e r n a lnoPanic notDead ( \_ r o l l o v e r I d ) nonReentrant { 442R o l l o v e rs t o r a g er o l l o v e r \_ = r o l l o v e r s \[ \_ r o l l o v e r I d \] ; 443i f( r o l l o v e r \_ . in vestor LastUpd ates \[ \_tranche \] \[msg.s e n d e r\] == 0) { 444r o l l o v e r \_ . inves torLast Update s \[ \_tranche \] \[msg.s e n d e r\] = 1; 445} 446{ 447Rounds t o r a g eround\_ = r o l l o v e r \_ . rounds \[ r o l l o v e r \_ . thisRound + 1 \] ; 448u i n t 2 5 6ccoId = round\_ . ccoId ; 449r e q u i r e( ccoId != 0 ,"No CCO to deposit in yet") ; 450r e q u i r e( ccoManager . canDeposit ( ccoId ) ,"CCO not in deposit state") ; 451TrancheRounds t o r a g etrancheRound\_ = round\_ . tranches \[ \_tranche \] ; 452OLib . I n v e s t o rs t o r a g einvestor\_ = trancheRound\_ . i n v e s t o r s \[msg.s e n d e r\] ; 453u i n t 2 5 6t o t a l = trancheRound\_ . newDeposited += \_amount ; 454u i n t 2 5 6userSum = 455investor\_ . userSums .l e n g t h> 0 456? investor\_ . userSums \[ investor\_ . userSums .l e n g t h−1\] + \_amount 457: \_amount ; 458investor\_ . prefixSums .push( t o t a l ) ; 459investor\_ . userSums .push( userSum ) ; 23/30PeckShield Audit Report #: 2021-112 Public 460} 461i f( 462r o l l o v e r \_ . inves torLast Update s \[ \_tranche \] \[msg.s e n d e r\] < 463r o l l o v e r \_ . thisRound + 1 464) { 465(u i n t 2 5 6shares ,u i n t 2 5 6excess ) = 466\_updateInvestor (msg.s e n d e r, \_ r o l l o v e r I d , \_tranche ) ; 467r o l l o v e r \_ . inves torLast Update s \[ \_tranche \] \[msg.s e n d e r\] = 468r o l l o v e r \_ . thisRound + 4691; 470i f( excess > \_amount) { 471r o l l o v e r \_ . a s s e t s \[ \_tranche \] . s a f e T r a n s f e r (msg.s e n d e r, excess−\_amount) ; 472}e l s e{ 473\_amount−= excess ; 474} 475i f( sha re s > 0) { 476r o l l o v e r \_ . r o l l o v e r T o k e n s \[ \_tranche \] . mint (msg.s e n d e r, sh ar es ) ; 477} 478} 479r o l l o v e r \_ . a s s e t s \[ \_tranche \] . safeTransferFrom ( 480msg.s e n d e r, 481a d d r e s s(t h i s) , 482\_amount 483) ; 484e m i tDeposited (msg.s e n d e r, \_ r o l l o v e r I d , \_amount) ; 485} Listing 3.14:RolloverCCO::deposit() RecommendationRevise thedeposit()logic inRolloverCCOto transfer user funds (viatransferFrom ()at line479) when the excess is already more than the intended amount for deposit. StatusThis issue has been fixed in this commit:5162589. 3.11 Potentially Repeated Excess Returns Of RolloverCCO •ID: PVE-011 •Severity: Medium •Likelihood: Medium •Impact: Medium •Target:RolloverCCO •Category: Business Logic \[7\] •CWE subcategory: CWE-841 \[4\] Description As mentioned in Section 3.10, theOndoprotocol supportsRolloverCCOthat can automate the invest- ment process by investing in a series of similar CCOs. Our analysis shows an issue that may result in multiple returns of the same excess amount. 24/30PeckShield Audit Report #: 2021-112 Public To elaborate, the protocol starts with the round number0and participating users can calldeposit ()to invest funds into theRolloverCCOcontract. When themigrate()function is called to initiate the investment into the nextCCO, the first-time investment executes the\_firstInvest()routine (line 618), which properly advances therollover\_.thisRoundto1(line771). 611f u n c t i o nmigrate (u i n t 2 5 6\_ r o l l o v e r I d , S l i p p a g e S e t t i n g smemory\_slippage ) 612e x t e r n a l 613noPanic 614notDead ( \_ r o l l o v e r I d ) 615onlyCreator ( \_ r o l l o v e r I d ) 616{ 617i f( r o l l o v e r s \[ \_ r o l l o v e r I d \] . thisRound == 0) { 618\_ f i r s t I n v e s t ( 619\_ r o l l o v e r I d , 620\_slippage . seniorMinInvest , 621\_slippage . j u n i o r M i n I n v e s t 622) ; 623}e l s e{ 624\_migrate ( \_ r o l l o v e r I d , \_slippage ) ; 625} 626} Listing 3.15:RolloverCCO::migrate() 735f u n c t i o n\_ f i r s t I n v e s t ( 736u i n t 2 5 6\_ r o l l o v e r I d , 737u i n t 2 5 6\_seniorMinInvest , 738u i n t 2 5 6\_juniorMinInvest 739)i n t e r n a l{ 740R o l l o v e rs t o r a g er o l l o v e r \_ = r o l l o v e r s \[ \_ r o l l o v e r I d \] ; 741Rounds t o r a g eround\_ = r o l l o v e r \_ . rounds \[ 1 \] ; 742u i n t 2 5 6ccoId = round\_ . ccoId ; 743r e q u i r e( round\_ . ccoId != 0 ,"CCO not set") ; 744TrancheRounds t o r a g esrRound = round\_ . tranches \[ OLib . Tranche . Senior \] ; 745TrancheRounds t o r a g ejrRound = round\_ . tranches \[ OLib . Tranche . Junior \] ; 746r o l l o v e r \_ . a s s e t s \[ OLib . Tranche . Senior \] . s a f e I n c r e a s e A l l o w a n c e ( 747a d d r e s s( ccoManager ) , 748srRound . newDeposited 749) ; 750r o l l o v e r \_ . a s s e t s \[ OLib . Tranche . Junior \] . s a f e I n c r e a s e A l l o w a n c e ( 751a d d r e s s( ccoManager ) , 752jrRound . newDeposited 753) ; 754ccoManager . depositFromRollover ( 755ccoId , 756\_ r o l l o v e r I d , 757srRound . newDeposited , 758jrRound . newDeposited 759) ; 760ccoManager . i n v e s t ( ccoId , \_seniorMinInvest , \_juniorMinInvest ) ; 761( srRound . invested , jrRound . i n v e s t e d ) = ccoManager . r o l l o v e r C l a i m ( 762ccoId , 25/30PeckShield Audit Report #: 2021-112 Public 763\_ r o l l o v e r I d 764) ; 765srRound . deposited = srRound . i n v e s t e d ; 766jrRound . deposited = jrRound . i n v e s t e d ; 767srRound . newInvested = srRound . i n v e s t e d ; 768jrRound . newInvested = jrRound . i n v e s t e d ; 769srRound . sh are s = srRound . i n v e s t e d ; 770jrRound . sha re s = jrRound . i n v e s t e d ; 771r o l l o v e r \_ . thisRound = 1; 772} Listing 3.16:RolloverCCO:: \_firstInvest () After that, a user may callclaim(), which cascadingly callsupdateInvestorDistribute()to claim the excess amount (line541). Moreover, if the user callsdeposit()one more time, theifcondi- tion (lines461 − 463) is satisfied to execute thethen-branch, which includes the\_updateInvestor() execution. This execution allows the current depositing user to claim the excess amount a second time. 492f u n c t i o nclaim (u i n t 2 5 6\_ r o l l o v e r I d , OLib . Tranche \_tranche ) 493e x t e r n a l 494noPanic 495notDead ( \_ r o l l o v e r I d ) 496nonReentrant 497{ 498R o l l o v e rs t o r a g er o l l o v e r \_ = r o l l o v e r s \[ \_ r o l l o v e r I d \] ; 499i f( 500r o l l o v e r \_ . inves torLast Update s \[ \_tranche \] \[msg.s e n d e r\] != 501r o l l o v e r \_ . thisRound + 1 502) { 503\_ u p d a t e I n v e s t o r D i s t r i b u t e (msg.s e n d e r, \_ r o l l o v e r I d , \_tranche ) ; 504} 505} Listing 3.17:RolloverCCO::claim() 437f u n c t i o nd e p o s i t ( 438u i n t 2 5 6\_ r o l l o v e r I d , 439OLib . Tranche \_tranche , 440u i n t 2 5 6\_amount 441)e x t e r n a lnoPanic notDead ( \_ r o l l o v e r I d ) nonReentrant { 442R o l l o v e rs t o r a g er o l l o v e r \_ = r o l l o v e r s \[ \_ r o l l o v e r I d \] ; 443i f( r o l l o v e r \_ . in vestor LastUpd ates \[ \_tranche \] \[msg.s e n d e r\] == 0) { 444r o l l o v e r \_ . inves torLast Update s \[ \_tranche \] \[msg.s e n d e r\] = 1; 445} 446{ 447Rounds t o r a g eround\_ = r o l l o v e r \_ . rounds \[ r o l l o v e r \_ . thisRound + 1 \] ; 448u i n t 2 5 6ccoId = round\_ . ccoId ; 449r e q u i r e( ccoId != 0 ,"No CCO to deposit in yet") ; 450r e q u i r e( ccoManager . canDeposit ( ccoId ) ,"CCO not in deposit state") ; 451TrancheRounds t o r a g etrancheRound\_ = round\_ . tranches \[ \_tranche \] ; 26/30PeckShield Audit Report #: 2021-112 Public 452OLib . I n v e s t o rs t o r a g einvestor\_ = trancheRound\_ . i n v e s t o r s \[msg.s e n d e r\] ; 453u i n t 2 5 6t o t a l = trancheRound\_ . newDeposited += \_amount ; 454u i n t 2 5 6userSum = 455investor\_ . userSums .l e n g t h> 0 456? investor\_ . userSums \[ investor\_ . userSums .l e n g t h−1\] + \_amount 457: \_amount ; 458investor\_ . prefixSums .push( t o t a l ) ; 459investor\_ . userSums .push( userSum ) ; 460} 461i f( 462r o l l o v e r \_ . inves torLast Update s \[ \_tranche \] \[msg.s e n d e r\] < 463r o l l o v e r \_ . thisRound + 1 464) { 465(u i n t 2 5 6shares ,u i n t 2 5 6excess ) = 466\_updateInvestor (msg.s e n d e r, \_ r o l l o v e r I d , \_tranche ) ; 467r o l l o v e r \_ . inves torLast Update s \[ \_tranche \] \[msg.s e n d e r\] = 468r o l l o v e r \_ . thisRound + 4691; 470i f( excess > \_amount) { 471r o l l o v e r \_ . a s s e t s \[ \_tranche \] . s a f e T r a n s f e r (msg.s e n d e r, excess−\_amount) ; 472}e l s e{ 473\_amount−= excess ; 474} 475i f( sha re s > 0) { 476r o l l o v e r \_ . r o l l o v e r T o k e n s \[ \_tranche \] . mint (msg.s e n d e r, sh ar es ) ; 477} 478} 479r o l l o v e r \_ . a s s e t s \[ \_tranche \] . safeTransferFrom ( 480msg.s e n d e r, 481a d d r e s s(t h i s) , 482\_amount 483) ; 484e m i tDeposited (msg.s e n d e r, \_ r o l l o v e r I d , \_amount) ; 485} Listing 3.18:RolloverCCO::deposit() RecommendationRevise thedeposit()to avoid repeated claims of any excess amount after investment. StatusThis issue has been resolved. 27/30PeckShield Audit Report #: 2021-112 Public 4 | Conclusion In this audit, we have analyzed the Ondo design and implementation. The system presents a unique, robust offering as a decentralized protocol to allow investors to shift the risk and reward balance between each other. The current code base is well structured and neatly organized. Those identified issues are promptly confirmed and fixed. Meanwhile, we need to emphasize thatSolidity-basedsmart contracts as a whole are still in an early, but exciting stage of development. To improve this report, we greatly appreciate any constructive feedbacks or suggestions, on our methodology, audit findings, or potential gaps in scope/coverage. 28/30PeckShield Audit Report #: 2021-112 Public References \[1\] MITRE. CWE-1126: Declaration of Variable with Unnecessarily Wide Scope. https://cwe. mitre.org/data/definitions/1126.html. \[2\] MITRE. CWE-287: Improper Authentication. https://cwe.mitre.org/data/definitions/287.html. \[3\] MITRE. CWE-563: Assignment to Variable without Use. https://cwe.mitre.org/data/ definitions/563.html. \[4\] MITRE. CWE-841: Improper Enforcement of Behavioral Workflow. https://cwe.mitre.org/ data/definitions/841.html. \[5\] MITRE. CWE CATEGORY: 7PK - Security Features. https://cwe.mitre.org/data/definitions/ 254.html. \[6\] MITRE. CWE CATEGORY: Bad Coding Practices. https://cwe.mitre.org/data/definitions/ 1006.html. \[7\] MITRE. CWE CATEGORY: Business Logic Errors. https://cwe.mitre.org/data/definitions/ 840.html. \[8\] MITRE. CWE VIEW: Development Concepts. https://cwe.mitre.org/data/definitions/699. html. \[9\] OWASP. Risk Rating Methodology. https://www.owasp.org/index.php/OWASP\_Risk\_ Rating\_Methodology. 29/30PeckShield Audit Report #: 2021-112 Public \[10\] PeckShield. PeckShield Inc. https://www.peckshield.com. 30/30PeckShield Audit Report #: 2021-112
---
# Unknown
January 25th 2022— Quantstamp Verified Ondo Finance 3 This audit report was prepared by Quantstamp, the leader in blockchain security. Executive Summary Type Yield Aggregator Auditors Mohsen Ahmadvand,Senior Research Engineer Poming Lee,Research Engineer Timeline 2021-12-01through2021-12-22 EVM London Languages Solidity Methods Architecture Review, Unit Testing, Functional Testing, Computer-Aided Verification, Manual Review Specification None Documentation Quality Medium Test Quality Undetermined Source Code RepositoryCommit protocol-devb574763 Nonef2c7b97 (re-audit) Total Issues 27(10 Resolved) High Risk Issues 4(2 Resolved) Medium Risk Issues 1(1 Resolved) Low Risk Issues 7(3 Resolved) Informational Risk Issues 11(4 Resolved) Undetermined Risk Issues 4(0 Resolved) High Risk The issue puts a large number of users’ sensitive information at risk, or is reasonably likely to lead to catastrophic impact for client’s reputation or serious financial implications for client and users. Medium Risk The issue puts a subset of users’ sensitive information at risk, would be detrimental for the client’s reputation if exploited, or is reasonably likely to lead to moderate financial impact. Low Risk The risk is relatively small and could not be exploited on a recurring basis, or is a risk that the client has indicated is low- impact in view of the client’s business circumstances. Informational The issue does not post an immediate risk, but is relevant to security best practices or Defence in Depth. Undetermined The impact of the issue is uncertain. Unresolved Acknowledged the existence of the risk, and decided to accept it without engaging in special efforts to control it. Acknowledged The issue remains in the code but is a result of an intentional business or design decision. As such, it is supposed to be addressed outside the programmatic means, such as: 1) comments, documentation, README, FAQ; 2) business processes; 3) analyses showing that the issue shall have no negative consequences in practice (e.g., gas analysis, deployment settings). Resolved Adjusted program implementation, requirements or constraints to eliminate the risk. Mitigated Implemented actions to minimize the impact or likelihood of the risk. Summary of Findings This audit was done on a subset of contracts in the Ondo repository (an exhaustive list of contracts can be found in the appendix). In our incremental audit we identified four high, one medium, six low, eleven informational, and four undetermined-severity issues. Two of the high-severity issues are logical problems. Such issues should be detected through extensive testing. The other two high-severity issues relate to the possibility of malicious behavior by the privileged roles in the protocol. The platform heavily relies on several external protocols (Sushiswap, Uniswap, Pancake, etc.) across several chains. Consequently, Ondo will inherit all the vulnerabilities in its external dependencies. A large portion of the code duplicate of strategies. This makes code maintenance and increases the chances of pitfalls. IDDescriptionSeverityStatus QSP-1 can possibly inflate SushiStakingV2Strategy.depositIntoChefvault.shares High Fixed QSP-2 deducts 2x LP per call DopexStrategy.removeLp High Fixed QSP-3 enables the guardian role to execute arbitrary transactions multiexcall High Acknowledged QSP-4 always setsto \_updateInvestorinvestorLastUpdates0 High Acknowledged QSP-5 Use of unsafe transfers Medium Fixed QSP-6 can potentially suffer from high slippages EdenStrategy.harvest Low Fixed QSP-7 andcalls are suceptible to frontrunning attacks uniRouter02.removeLiquidityuniRouter02.addLiquidity Low Acknowledged QSP-8 Ownership can be renounced Low Acknowledged QSP-9 in theevent is faulty amountTransferredFromUserDeposited Low Fixed QSP-10 Unintended unstake in the Eden strategy Low Fixed QSP-11 of tranche tokens can cause inconsistencies tokenMinting Low Acknowledged QSP-12 doesn't check inputs RolloveVault.\_getUpdatedInvestor Informational Unresolved QSP-13 Discrepancy between comments and implementation of newRollover Informational Fixed QSP-14 Why do rounds start from 1 and not zero? Informational Acknowledged QSP-15 Heavy storage usage (expensive gas) Informational Acknowledged QSP-16 of a vault to a user investing throughis not always valid userCapRollover Informational Acknowledged QSP-17 Use of initialised variables Informational Fixed QSP-18 Ignored return values Informational Acknowledged QSP-19 Missing zero input checks Informational Fixed QSP-20 Dependency on several external contracts Informational Acknowledged QSP-21 Allowance Double-Spend Exploit Informational Acknowledged QSP-22 The enablement ofof tranche tokens is not checked tokenMinting Informational Fixed QSP-23 Privileged Roles and Ownership Undetermined Acknowledged QSP-24 Invalid and detrimental paths can be supplied toand \_seniorToJuniorPath\_juniorToSeniorPath Undetermined Acknowledged QSP-25 skips one round getNextVault Undetermined Acknowledged QSP-26 Potentially dangreous use of strict equality in createVault Undetermined Acknowledged QSP-27 function lets the guardian to execute arbitrary transfers excall Low Unresolved QuantstampAuditBreakdown Quantstamp's objective was to evaluate the repository for security-related issues, code quality, and adherence to specification and best practices. Possible issues we looked for included (but are not limited to): Transaction-ordering dependence• Timestamp dependence• Mishandled exceptions and call stack limits• Unsafe external calls• Integer overflow / underflow• Number rounding errors• Reentrancy and cross-function vulnerabilities• Denial of service / logical oversights• Access control• Centralization of power• Business logic contradicting the specification• Code clones, functionality duplication• Gas usage• Arbitrary token minting• Methodology The Quantstampauditingprocess follows a routine series of steps: 1.Code review that includes the following i.Review of the specifications, sources, and instructions provided to Quantstamp to make sure we understand the size, scope, and functionality of the smart contract. ii.Manual review of code, which is the process of reading source code line-by-line in an attempt to identify potential vulnerabilities. iii.Comparison to specification, which is the process of checking whether the code does what the specifications, sources, and instructions provided to Quantstamp describe. 2.Testing and automated analysis that includes the following: i.Test coverage analysis, which is the process of determining whether the test cases are actually covering the code and how much code is exercised when we run those test cases. ii.Symbolic execution, which is analyzing a program to determine what inputs cause each part of a program to execute. 3.Best practices review, which is a review of the smart contracts to improve efficiency, effectiveness, clarify, maintainability, security, and control based on the established industry and academic practices, recommendations, and research. 4.Specific, itemized, and actionable recommendations to help you take steps to secure your smart contracts. Toolset The notes below outline the setup and steps performed in the process of thisaudit. Setup Tool Setup: v0.8.1•Slither v0.2.7•Mythril Steps taken to run the tools: 1.Installed the Slither tool: pip install slither-analyzer 2.Run Slither from the project directory: slither . 3.Installed the Mythril tool from Pypi: pip3 install mythril 4.Ran the Mythril tool on each contract: myth -x path/to/contract Findings QSP-1can possibly inflate SushiStakingV2Strategy.depositIntoChefvault.shares Severity:High Risk FixedStatus: ,File(s) affected:contracts/strategies/SushiStakingV2Strategy.sol:483contracts/strategies/SushiStrategyLP.sol:335 The implementation ofintreats vault shares slightly differently than the corresponding implementation in.Description:depositIntoChefSushiStakingV2StrategySushiStrategyLP SushiStakingV2Strategy: if (poolData.totalLp == 0 || poolData.totalShares == 0) { poolData.totalShares = \_amount \* sharesToLpRatio; poolData.totalLp = \_amount; vault.shares = \_amount \* sharesToLpRatio; } else { uint256 shares = (\_amount \* poolData.totalShares) / poolData.totalLp; poolData.totalShares += shares; vault.shares += shares; //HERE the shares are added to the current value poolData.totalLp += \_amount; } if (poolData.totalLp == 0 || poolData.totalShares == 0) { poolData.totalShares = \_amount; poolData.totalLp = \_amount; vault.shares = \_amount; } else { uint256 shares = (\_amount \* poolData.totalShares) / poolData.totalLp; poolData.totalShares += shares; vault.shares = shares; // HERE the shares are simply assigned poolData.totalLp += \_amount; } It is unclear why the two functions differ in vault share assignments. Ensure that the identified discrepancy is not a bug. Consider writing test cases for the captured logical discrepancy between the two contracts.Recommendation: QSP-2deducts 2x LP per call DopexStrategy.removeLp Severity:High Risk FixedStatus: File(s) affected:contracts/strategies/DopexStrategy.sol:145 Thefunction callsthat already includes aamount deduction: contracts/strategies/DopexStrategy.sol:115Description:removeLpwithdrawFromStakingtotalLp function withdrawFromStaking(uint256 \_amount) internal { require(\_amount > 0, "totalLP must be greater than 0"); stakingContract.withdraw(\_amount); totalLP -= \_amount; } Nevertheless, thefunction includes anotheramount deduction resulting in a 2x value loss.removeLptotalLp Remove the amount deduction from thefunction. Consider adding test cases capturing this very bug for all your strategy contracts.Recommendation:removeLp QSP-3enables the guardian role to execute arbitrary transactions multiexcall Severity:High Risk AcknowledgedStatus: ,,File(s) affected:contracts/strategies/UniswapStrategy.solcontracts/strategies/SushiStakingV2Strategy.solcontracts/strategies/AUniswapStrategy.sol Thefunction provides batch execution to the guardian role. The user with such a role can execute any harmful transactions, e.g., to deplete the funds.Description:multiexcall Ensure that users are informed about the guardians power in your protocol. Consider using multi-sig with a large enough set of users to mitigate the risk.Recommendation: Response from Ondo:Update: can be called by Guardian which is in turn a multisig and community is aware of this functionalityMultiexcall QSP-4always setsto \_updateInvestorinvestorLastUpdates0 Severity:High Risk AcknowledgedStatus: File(s) affected:contracts\\RolloverVault.sol always setstoinstead of updating it to the index of the current round. This can potentially break the rounds accounting logic. Description:\_updateInvestor:L447investorLastUpdates0 Ensure that the stated code does not lead to problems. We assume the correct behavior should be assigningto.Recommendation:investorLastUpdatesrollover.thisRound + 1 Response from Ondo: > the internal variable investorLastUpdates is used to find the round number in which investor's funds are associated with. This variable is updated whenever there is change of state to investor's funds i.e., claim, withdraw or deposits. When a new deposit is made, the round is updated to the round to which investor's funds are associated. When claim, withdraw or a new deposit happens, if investorLastUpdates is 0 - then the shares and excess for the investor are computed from clean state. Else, existing shares,excess from the current round are extracted and the investorLastUpdates is set to 0 because all the shares and excess are returned to the investor. Update: QSP-5 Use of unsafe transfers Severity:Medium Risk FixedStatus: File(s) affected:contracts/strategies/helpers/AlchemixUserReward.sol The contract does not check whether the transfer was succesful or not. More importantly, the usage of transfer is discouraged as it may run out of gas.Description: Consider using openzeppelin'sthat reverts in case of failure.Recommendation:safeTransfer QSP-6can potentially suffer from high slippages EdenStrategy.harvest Severity:Low Risk FixedStatus: File(s) affected:contracts/strategies/EdenStrategy.sol Thefunction does not employ minimum expected value checks. This can enable attacker (bots) to potentially utilize flash loans imposing high slippages on the protocol.Description:harvest Consider enforcing minimum expected value checks.Recommendation: QSP-7andcalls are suceptible to frontrunning attacks uniRouter02.removeLiquidityuniRouter02.addLiquidity Severity:Low Risk AcknowledgedStatus: ,File(s) affected:contracts/strategies/UniswapStrategy.solcontracts/strategies/AUniswapStrategy.sol We identified several calls to theandfunctions that set the minimum expected tokens to 0. This way of interacting with AMM pools is susceptible to sandwich attacks. Description:addLiquiditiyremoveLiquidity Here are code pointers to insecure AMM invocations: 1. contracts/strategies/AUniswapStrategy.sol:358~366 2. contracts/strategies/AUniswapStrategy.sol:456~463 3. contracts/strategies/AUniswapStrategy.sol:504~511 4. contracts/strategies/UniswapStrategy.sol:321~329 Consider computing the minimum expected values prior to the calls and checking them in your contracts.Recommendation: Response from Ondo:Update: We currently have checks outside the functions which make sure a certain slippage doesn’t exceed but we acknowledge that we can try to do better and use non 0 values. QSP-8 Ownership can be renounced Severity:Low Risk AcknowledgedStatus: File(s) affected:Ondo.sol has afunction. Although it can only be called by the owner, contracts with (accidentally or maliciously) renounced ownerships can cause a denial of service. Description:Ownable.solrenounceOwnership() Particularly, Ondo token's transferable state can no longer be set after ownership is renounced. Consider using a two-step ownership transfer scheme and disabling thefunction.Recommendation:renounceOwnership Response from Ondo:Update: Ondo.sol is taken from Compound and uses the same trust assumptions that Compound token does. The owner will be a multis with 3 of 5 at least and hence its okay to keep this for now. QSP-9in theevent is faulty amountTransferredFromUserDeposited Severity:Low Risk FixedStatus: File(s) affected:contracts/RolloverVault.sol:412~413 The amount deposited depends on the exceeding amount. If the exceeding amount is larger than the requested deposit amount, then nothing is transferred from the user. Instead, the diff between the exceeding amount and the intended deposit amount is transferred back to the user. In the emitted event thecaptures an invalid value. This results in incorrect information being displayed to the users in the frontend. Description: amountTransferredFromUser emit Deposited( msg.sender, \_rolloverId, uint256(\_tranche), \_amount, int256(\_amount) - int256(excess), shares ); Fix thevalue in the emit.Recommendation:amountTransferredFromUser QSP-10 Unintended unstake in the Eden strategy Severity:Low Risk FixedStatus: File(s) affected:contracts/strategies/EdenStrategy.sol Wheneveris smaller than, the functionwill not restake (i.e., calling) after unstaking on, leaving all the remaining unstaked and kept in the strategy contract. Description:edenAmount10000harvestdepositIntoStakingL158totalLP Make sure to restake at the end of functionin all conditions.Recommendation:harvest QSP-11of tranche tokens can cause inconsistencies tokenMinting Severity:Low Risk AcknowledgedStatus: File(s) affected:contracts/Registry.sol The functions in:-allowto enable/disable theof tranche tokens literally "at any time". This could lead to internal accounting problems, such as part of the users getting the tranche tokens where some of the users do not. Description:contracts/Registry.solL78L84OLib.GOVERNANCE\_ROLEtokenMinting This feature should be limited, removed, or at least having all the changes to the platform carefully estimated by the admin team every time before enabling/disabling thisRecommendation: feature. Response from Ondo:Update: is only given to a governance multis which is 3 of 5 and will never be used to turn on token\_minting and turn it off, we are aware of the inconsistencies that can occur if tokenMinting is turned on and off. It's meant to be used as a one time switch to turn on tokenMinting. GOVERNANCE\_ROLE QSP-12doesn't check inputs RolloveVault.\_getUpdatedInvestor Severity:Informational UnresolvedStatus: File(s) affected:contracts/RolloverVault.sol:220~221 doesn't check if,inputs actually exist. It is indirectly consumed by several state-changing functions, viz. ,,,, and. Description:RolloveVault.getUpdatedInvestor\_rolloverId\_tranche \_updateInvestor\_updateInvestorDistributedepositwithdrawclaim Ensure that invalid inputs do not have an impact on the listed functions by adding test cases. Consider adding checks if inputs are valid.Recommendation: The newly added require statement checks if creator is not address zero:Update: require(rollover.creator != address(0), "Invalid rolloverId"); The check should verify if the provided,values exist.\_rolloverId\_tranche QSP-13 Discrepancy between comments and implementation of newRollover Severity:Informational FixedStatus: File(s) affected:contracts/RolloverVault.sol Thefunction reverts upon a zero value for theargument. However, the comment indicates that in such cases params should be used as the basis to create a new rollover: \`\`\`\* @dev If \_vaultId is 0, use \_params for everything. Otherwise, inherit most params from \_vaultId instance Description:newRollover\_vaultId • @param \_vaultId Optional Vault to inherit parameters from ...require(\_vaultId != 0, "Invalid vaultId"); \`\`\` Ensure that the revert reflects the intended behavior.Recommendation: QSP-14 Why do rounds start from 1 and not zero? Severity:Informational AcknowledgedStatus: File(s) affected:contracts/RolloverVault.sol:231 The rollover.rounds considers index 1 as the starting element. It is not clear why index 0 is skipped.Description: function newRollover(uint256 \_vaultId, OLib.RolloverParams memory \_params) Rollover storage rollover = rollovers\[rolloverId\]; require(rollover.rounds\[1\].vaultId == 0, "Already exists"); ... rollover.rounds\[1\].vaultId = \_vaultId; Ensure that the logic is correct.Recommendation: Response from Ondo:Update: Round 0 is considered a special round which means open for deposits. QSP-15 Heavy storage usage (expensive gas) Severity:Informational AcknowledgedStatus: File(s) affected:contracts/RolloverVault.sol The implementation is extremely storage-intensive. This can lead to expensive transactions or possibly denial of service if a transaction becomes larger than one block.Description: rollovers -> mapping(uint256 => Rollover) internal rollovers; struct Rollover { address creator; address strategist; mapping(uint256 => Round) rounds; mapping(OLib.Tranche => IERC20) assets; mapping(OLib.Tranche => ITrancheToken) rolloverTokens; mapping(OLib.Tranche => mapping(address => uint256)) investorLastUpdates; uint256 thisRound; bool dead; } struct Round { uint256 vaultId; mapping(OLib.Tranche => TrancheRound) tranches; } struct TrancheRound { uint256 deposited; uint256 invested; // Total, if any, actually invested uint256 redeemed; // After Vault is done, total tokens redeemed for LP uint256 shares; uint256 newDeposited; uint256 newInvested; mapping(address => OLib.Investor) investors; } struct Investor { uint256\[\] userSums; uint256\[\] prefixSums; bool claimed; bool withdrawn; } Round storage round = rollover.rounds\[rollover.thisRound + 1\]; -> round.tranches\[\_tranche\]; OLib.Investor storage investor = trancheround.investors\[msg.sender\]; investor.userSums\[...\] vaultView.assets\[uint256(\_tranche)\] For instance, storing every deposited amount () might not be necessary to achieve the intended goals.userSums Perform a gas usage analysis. Consider refactoring the code to use less storage when possible.Recommendation: Response from Ondo:Update: This is the design of contracts and cannot be changed at this stage, we will take this into consideration for the next iterations QSP-16of a vault to a user investing throughis not always valid userCapRollover Severity:Informational AcknowledgedStatus: File(s) affected:contracts/RolloverVault.sol Currently for the Rollover contract, whenever a user calls, the contract will check if, whereis for the vault for the round. However, if the user already invested before and never calls thatfunction again, this check will never be performed again. And this restriction will no longer be valid when theof vaults in the following rounds is smaller than theof the user. Description:deposituserSum <= userCapuserCap rollover.thisRound + 1deposit userCapuserSum There is no solution to fix this problem without redesigning the mechanism. We recommend the admin team to evaluate if this level of violation to the restriction is acceptable.Recommendation: Response from Ondo:Update: The check is to stop users from depositing into the vault beyond the usercap. However, if the usercap is exceeded in the subsequent rounds we shouldn’t limit rounds with this restriction. That is how the contract is designed QSP-17 Use of initialised variables Severity:Informational FixedStatus: Several usage of uninitialised variables were detected throughout the source code:Description: EdenStrategy.harvest(uint256).wethAmount (contracts/strategies/EdenStrategy.sol#161) is a local variable never initialized BondStrategy.harvest(uint256).usdcAmount (contracts/strategies/BondStrategy.sol#157) is a local variable never initialized AlchemixLPStrategy.\_compound().ethAmount (contracts/strategies/AlchemixLPStrategy.sol#328) is a local variable never initialized RolloverVault.deposit(uint256,OLib.Tranche,uint256).excess (contracts/RolloverVault.sol#358) is a local variable never initialized AlchemixLPStrategy.\_compound().amountToSwap (contracts/strategies/AlchemixLPStrategy.sol#372) is a local variable never initialized RolloverVault.\_getUpdatedInvestor(address,uint256,OLib.Tranche).shares (contracts/RolloverVault.sol#199) is a local variable never initialized SushiStakingV2Strategy.\_compound(IERC20,SushiStakingV2Strategy.PoolData).amountToSwap (contracts/strategies/SushiStakingV2Strategy.sol#408) is a local variable never initialized DopexStrategy.harvest(uint256).wethAmount (contracts/strategies/DopexStrategy.sol#160) is a local variable never initialized Ensure to initialise every variable before use to avoid unexpected results.Recommendation: QSP-18 Ignored return values Severity:Informational AcknowledgedStatus: ,File(s) affected:contracts/RolloverVault.sol:667~674contracts/RolloverVault.sol:799~800 andignore return values ofand, respectively.Description:RolloverVault.\_migrateRolloverVault.\_investAllPairsVault.redeemAllPairsVault.invest Consider not returning anything if the values are not needed.Recommendation: Response from Ondo:Update: we need these return values to get minimums to prevent slippage while executing non-rollover vault invest/redeem QSP-19 Missing zero input checks Severity:Informational FixedStatus: The listed contracts do not check the input parameters:Description: 1.:: addressin. contracts\\SampleFeeCollector.solL23vaultconstructor 2.::. contracts\\TrancheToken.solL37\_vault 3.:-:and. contracts\\Registry.solL35L37\_governance\_weth Consider checking the input parameters.Recommendation: QSP-20 Dependency on several external contracts Severity:Informational AcknowledgedStatus: The protocol relies on functionalities of external contracts such as: UniswapV2, Sushiswap, Quickswap, Pancakeswap, etc. Therefore, security of the project depends on these contracts. While we are unaware of any immediate issues, it is important to note that DeFi protocols can be susceptible to flash loan attacks, market manipulation, computational errors, etc. Description: We strongly recommend to monitor all the external contracts and follow up on their vulnerabilities. Consider integrating logics to redeem all funds quickly from strategies in case of zero-day hacks. Recommendation: Response from Ondo:Update: We will monitor all the contracts that we are interacting with and have a test suite to test it with forking QSP-21 Allowance Double-Spend Exploit Severity:Informational AcknowledgedStatus: File(s) affected:contracts/TrancheToken.sol As it presently is constructed, the contract is vulnerable to the, as with other ERC20 tokens.Description:allowance double-spend exploit Exploit Scenario: 1.Alice allows Bob to transferamount of Alice's tokens () by calling themethod onsmart contract (passing Bob's address andas method arguments) NN>0approve()TokenN 2.After some time, Alice decides to change fromto() the number of Alice's tokens Bob is allowed to transfer, so she calls themethod again, this time passing Bob's address andas method arguments NMM>0approve() M 3.Bob notices Alice's second transaction before it was mined and quickly sends another transaction that calls themethod to transferAlice's tokens somewhere transferFrom()N 4.If Bob's transaction will be executed before Alice's transaction, then Bob will successfully transferAlice's tokens and will gain an ability to transfer anothertokens NM 5.Before Alice notices any irregularities, Bob callsmethod again, this time to transferAlice's tokens. transferFrom()M The exploit (as described above) is mitigated through use of functions that increase/decrease the allowance relative to its current value, such asand . Recommendation:increaseAllowance() decreaseAllowance() Pending community agreement on an ERC standard that would protect against this exploit, we recommend that developers of applications dependent on/ should keep in mind that they have to set allowance to 0 first and verify if it was used before setting the new value. Teams who decide to wait for such a standard should make these recommendations to app developers who work with their token contract. approve()transferFrom() Response from Ondo:Update: TrancheToken is mostly taken from open zeppelin and has the functions that are recommended, we will recommend the users to use increaseAllowance instead of approve. QSP-22 The enablement ofof tranche tokens is not checked tokenMinting Severity:Informational FixedStatus: File(s) affected:contracts\\AllPairVault.sol The functions that trigger mint do not check whether minting is enabled or not: The enablement ofof tranche tokens is not checked in:Description:tokenMinting 1.:- contracts\\AllPairVault.solL541L544 2.:- contracts\\AllPairVault.solL545L548 3.:- contracts\\AllPairVault.solL896L903 4.: contracts\\AllPairVault.solL1142 Consider checking whether the mint is enbaled before calling.Recommendation:mint QSP-23 Privileged Roles and Ownership Severity:Undetermined AcknowledgedStatus: File(s) affected:contracts\\AllPairVault.sol Smart contracts will often havevariables to designate the person with special privileges to make modifications to the smart contract. There are some actions that could have important consequences for end-users. Thein the Ondo platform is be able to execute arbitrary code on. Description:owner OLib.GUARDIAN\_ROLEcontracts\\AllPairVault.sol This centralization of power needs to be made clear to the users, especially depending on the level of privilege the contract allows to the owner.Recommendation: Response from Ondo:Update: Multiexcall can be called by Guardian which is in turn a multisig. QSP-24 Invalid and detrimental paths can be supplied toand \_seniorToJuniorPath\_juniorToSeniorPath Severity:Undetermined AcknowledgedStatus: File(s) affected:contracts/strategies/UniswapStrategy.sol andfunctions accepts any arbitrary conversion paths. Invalid paths (paths that do not end with junior or senior tranche tokens accordingly) can lead to undetermined issues in the protocol. Moreover, paths can have different economical characteristics. As constructed, the strategist role can set those paths. A strategist can potentially favour paths to their benefit and in determent to other users (e.g., to include their own pools by forcing unnecessary swaps to certain tokens). Description:setPathJuniorToSeniorsetPathSeniorToJunior Ensure the the path array's last element matches the senior and junior tranche tokens in theandfunctions, respectively. Inform the users (through the public-facing documentations) about the strategist's power in setting paths in the protocol. Consider enabling the protocol users to vote on the swap paths or use third-party contracts to compute paths with the highest returns. Recommendation:setPathJuniorToSeniorsetPathSeniorToJunior Response from Ondo:Update: It's done on purpose to allow for arbitrary paths if needed, this strategy is mostly used with our DAO partners who can request different tokens or different trades and we did not want to limit setting the paths QSP-25skips one round getNextVault Severity:Undetermined AcknowledgedStatus: File(s) affected:contracts/RolloverVault.sol:181 looks upin:Description:getNextVaultrollover.thisRound + 2rollover.rounds uint256 vaultId = rollover.rounds\[rollover.thisRound + 2\].vaultId; In the previous audit the look up index was.rollover.thisRound + 1 Ensure that the implementation is correct. Consider adding test cases to verity the correctness.Recommendation: Response from Ondo:Update: The implementation is correct. Added more tests to validate this. QSP-26 Potentially dangreous use of strict equality in createVault Severity:Undetermined AcknowledgedStatus: File(s) affected:contracts/AllPairVault.sol:337 Description: The createVault function sets thevalue to the passed input (). The function requires the startTime to be greater than/equal to the current block timestamp at line #267:Thereupon, the function checks if the startAt is strictly equal to the current block's timestamp to decide whether to set the vault\_.state to deposit (#337-#339): Description:startAt\_params.startTime require(\_params.startTime >= block.timestamp, "Invalid start time"); if (vault\_.startAt == block.timestamp) { vault\_.state = OLib.State.Deposit; } It unclear what will happen if the deposit state condition is not met (i.e.,). Given that the state of deposit can not be set otherwise, the contract may experience denial of service. It is not safe to rely on the block.timestamp to be what you expect it to be upon triggering a createVault call. vault\_.startAt != block.timestamp Ensure that the described circumstances does not lead to a denial of service. Consider turning the deposit state into a dynamically computed state, instead of storing it:Recommendation: function canDepositIntoVault view internal (){ return vault\_.startAt <= block.timestamp; } Response from Ondo:Update: This isn’t a bug, its an optimisation, the idea is that if the start time happens to be exactly the same as block time, then vault state changes to deposit. It is ensured that this does not cause a denial of service. QSP-27function lets the guardian to execute arbitrary transfers excall Severity:Low Risk UnresolvedStatus: File(s) affected:contracts/RolloverVault.sol The newly added function enables the guardian to execute arbitrary transfers:Description: function excall(address target, bytes calldata data) external isAuthorized(OLib.GUARDIAN\_ROLE) returns (bytes memory returnData) { bool success; (success, returnData) = target.call(data); require(success, "CF"); } It is not clear why the guardian needs to have such a privilege in the system. This can lead to fund losses if the guardian is compromised. Include the stated function in the public-facing documentation and justify the need for such a function. Consider using multisig for the guardian role.Recommendation: Automated Analyses Slither We analysed the findings and incorporated the relevant issues to the report. Adherence to Specification 1.:: should beinstead, otherwise should modify the warning message to. contracts\\AllPairVault.solL2721e61000000% Code Documentation 1.Consider describing the mechanism ofandin theand. contracts\\RolloverVault.solROLLOVER\_ROLE documentationsroles 2.:: mis-spell in word. contracts\\RolloverVault.solL37Rollove 3.:: mis-spell in word. contracts\\RolloverVault.solL42exces Adherence to Best Practices 1.Strategies seem to have a lot in common. The strategy logic entails depositing assets, tracking LP tokens, withdrawing and re-investing (compounding), and redeeming. This common logic is to a great extend duplicated across the contracts. Maintaining and securing all the duplicated code will have a huge overhead. Consider refactoring the code such that all the common codes reside in one single contract. By restoring to hooks you can have the flexibility of calling platform-specific codes to write platform-agnostic strategies. 2.: the use of class instancefor rollover tokens is confusing. Consider creating another class that inherits and named it asto improve the clarity of the code. contracts\\RolloverVault.solTrancheTokenTrancheToken RolloverToken 3.:the condition ">" is not possible. Consider reviewing the possibility of this condition again and make sure if the handling logic in is acceptable. contracts\\RolloverVault.solL731 L732 4.TODO in:. contracts\\strategies\\DopexStrategy.solL91 5.TODO in:. contracts\\strategies\\DopexStrategy.solL148 6.: consider adding a zero check to theof functionin order to make sure that an uninitialised vault could never get pass the check (i.e.,) in. contracts\\AllPairVault.sol\_params.strategistcreateVault address(vault\_.strategist) == address(0)L302 7.:please make sure that the strict equality checkin this line is intended, and cannot be replaced by. contracts\\AllPairVault.solL337==>= 8.: functionuses a listto record input dead tokens. This list does not guarantee the uniqueness of the dead tokens. This could lead to errors in the functionwhen trying to recycle the dead tokens. Please make sure that this condition does not happen. contracts\\Registry.soltokensDeclaredDeaddeadTokens recycleDeadTokens 9.is not initalized in the abstract class but used in some functionsis not initialized in the constructor of. However, it is used by some abstract function implementations. Both consumers of, viz. , and, do initializein their constructors. Nevertheless, it is a better practice to initialize all the used variables as part of the abstract class construtor. mainTokencontracts/strategies/ASushiswapStrategy.solmainToken ASushiswapStrategyASushiswapStrategy bsc/contracts/strategies/PancakeStrategyLP.solpolygon/contracts/strategies/QuickswapStrategyLP.solmainToken solidity constructor( address \_registry, address \_router, address \_rewardsFactory, address \_factory, address \_mainToken, address \_stakingRewardToken ) ASushiswapStrategy(\_mainToken /\*initialize ASushiswapStrategy.\_mainToken\*/, \_registry, \_router, \_factory) 10.apply the check-effects-interactions pattern to prevent re-entrancy attacks: 1.AUniswapStrategy.\_invest(uint256,uint256,uint256,uint256,uint256,uint256,uint256) (contracts/strategies/AUniswapStrategy.sol#225-259) 2.RolloverVault.\_migrate(uint256,IRollover.SlippageSettings) (contracts/RolloverVault.sol#659-723) 3.AllPairVault.\_withdraw(uint256,OLib.Tranche,address) (contracts/AllPairVault.sol#824-852) 4.SushiStakingV2Strategy.midTermDepositLp(IERC20,uint256) (contracts/strategies/SushiStakingV2Strategy.sol#190-219) 5.SushiStrategyLP.midTermDepositLp(IERC20,uint256) (contracts/strategies/SushiStrategyLP.sol#199-209) 6.RolloverVault.newRollover(uint256,OLib.RolloverParams) (contracts/RolloverVault.sol#231-302) 7.AlchemixLPStrategy.removeLp(uint256,uint256,address) (contracts/strategies/AlchemixLPStrategy.sol#247-271) 8.BondStrategy.removeLp(uint256,uint256,address) (contracts/strategies/BondStrategy.sol#134-143) 9.DopexStrategy.removeLp(uint256,uint256,address) (contracts/strategies/DopexStrategy.sol#136-146) 10.EdenStrategy.removeLp(uint256,uint256,address) (contracts/strategies/EdenStrategy.sol#138-147) 11.SushiStakingV2Strategy.removeLp(uint256,uint256,address) (contracts/strategies/SushiStakingV2Strategy.sol#159-185) 12.SushiStrategyLP.removeLp(uint256,uint256,address) (contracts/strategies/SushiStrategyLP.sol#158-182) 11.Consider declaring the following functions as external: 1.rescueTokens(address\[\],uint256\[\]) (contracts/OndoRegistryClientInitializable.sol#73-80) 2.authorized(bytes32,address) (contracts/Registry.sol#58-65) 3.paused() (contracts/Registry.sol#99-101) Test Results Test Suite Results 13 tests are failing. Network Info ============ > HardhatEVM: v2.6.2 > network: hardhat No need to generate any newer typings. (node:8413) Warning: Accessing non-existent property 'padLevels' of module exports inside circular dependency (Use \`node --trace-warnings ...\` to show where the warning was created) masterchefv2 dual incentive pool mcv2 vault lifecycle ✓ get assets (13584ms) ✓ create vaults (3996ms) ✓ deposit assets and fast-forward (10355ms) ✓ invest ALCX/ETH vault (35228ms) ✓ invest ETH/ALCX vault (6754ms) 1) get LP from the sushiswap pool and deposit 2) withdraw LP from ALCX/ETH vault 3) deposit LP in ALCX/ETH vault ✓ harvest (353ms) ✓ harvest (342ms) ✓ harvest (359ms) ✓ harvest (336ms) ✓ harvest (335ms) ✓ harvest (335ms) ✓ redeem ALCX/ETH vault (3252ms) ✓ redeem ETH/ALCX vault (745ms) EdenStrategy - WETH-EDEN helper 4) "before all" hook in "EdenStrategy - WETH-EDEN helper" BondStrategy - USDC-BOND helper USDC-BOND - deployment validation ✓ should not allow zero address for the staking address deploying uniswap strategy (609ms) ✓ should not allow zero address for the yieldfarm address deploying uniswap strategy ✓ should not allow zero address for the usdc address deploying uniswap strategy ✓ should not allow zero address for the bond address deploying uniswap strategy ✓ should not allow zero address for the usdcBondUniLp address deploying uniswap strategy USDC-BOND - vault lifecycle ✓ should allow Creator to create vault (1192ms) ✓ should NOT allow any one other than creator to create vault ✓ should allow investors to deposit assets in the junior tranche when with in the user and tranche cap (3701ms) ✓ should allow investors to deposit assets in the senior tranche when with in the user and tranche cap (2745ms) ✓ should not allow strategist to invest before the investAt time ✓ should not allow investors to deposit assets when exceeds usercap for the tranche ✓ should not allow investors to deposit assets in the live vault ✓ should allow investors to claim uninvested asset plus tranche tokens for the corresponding asset ✓ should not return tranche tokens on claim if enableTokens flag is disabled ✓ should allow investors to deposit ETH into Active vault only if the tranche is WETH ✓ should allow investors to claim ETH though the vault asset is WETH ✓ should allow performance fee to be set and changed by strategist on inactive vaults only ✓ should not allow performance fee to be more than a predetermined amount ✓ should be able to retrieve vault for specific vault index or a range of vault indexes ✓ should be able to retrieve vault for specific trancheToken address ✓ should be able to retrieve expected senior amount for the vault ✓ should be able to retrieve correct usercaps set in the vault ✓ should be able to retrieve all the correct details of vault investor like position, claimable and withdrawable balances, excess USDC-BOND vault behaviour - invest ✓ should allow strategist to invest - On invest one asset should go to 0 (12794ms) USDC-BOND vault behaviour - harvest and redeem ✓ should increase the amount of lp tokens in staking contract when harvest in strategy is called (44760ms) ✓ should not redeem if the slippage is too high (3367ms) ✓ should increase both sr and jr values on redeem (400ms) ✓ should calculate the correct amount of shares for given number of lp tokens ✓ should calculate the correct amount of lptokens for given number of shares ✓ should not compound if sushi rewards and second rewards are less than 10000 ✓ should convert all the sushi to the end asset in path\[0\] in pool and all reward tokens to the end asset path\[1\] in the pool and invest into LP ✓ should be able to get more LP with better reward paths. eg., instead of \[\[sushi,DAI\],\[LDO,ETH,DAI,WSTETH\]\] we should be able to use \[\[sushi,DAI\],\[LDO,ETH,DAI\]\] ✓ should be able to compound with senior uninvested leftover ✓ should be able to compound with junior uninvested leftover ✓ should be able to compound with no uninvested leftover ✓ should be able to compound when tokenA is leftover after investing both rewards into LP ✓ should be able to compound when tokenB is leftover after investing both rewards into LP USDC-BOND mid term deposits ✓ should allow investors to claim senior tranche tokens and excess (109ms) 5) should allow investors to claim junior tranche tokens and excess ✓ should allow investors to trade tranche tokens (119ms) ✓ should allow investors to withdraw LP tokens (525ms) ✓ should allow investors to deposit LP in the Live vault and get back tranche tokens (554ms) ✓ should allow harvest and redeem if all LP is withdrawn ✓ should not allow investors to deposit LP when vault is not Live ✓ should allow investors to deposit ETH into Active vault only if the tranch is WETH ✓ should allow investors to withdraw ETH even though the balance in strategy is WETH ✓ should allow investors to withdraw LP in the correct ratio by depositing tranche tokens. Only correct ratio of tranche tokens burnt and remaining left in the contract ✓ should allow governace to set performanceFee collector for vault ✓ should increase the amount of lp tokens in staking contract when harvest in strategy is called (472ms) ✓ should allow redeem and burn tranche tokens (1097ms) USDC-BOND emergency withdraw from Uniswap ✓ should allow governace to withdraw LP from uniswap to strategy (42ms) ✓ should not allow any one other than governace to call multiexcall ✓ should return error if multicall fails ✓ should allow guardian role to rescue the tokens from strategy (47ms) ✓ should not allow anyone other than guardian role to rescue the LP tokens withdrawn from mcv2 Claim ✓ Create vault (1373ms) ✓ Get some DAI ✓ Deposit on both sides (11687ms) ✓ Move to invest state (2627ms) ✓ Try to claim DAI (69ms) ✓ Try to claim ETH (70ms) ✓ Redeem funds (1897ms) ✓ Withdraw all funds (146ms) Create2 ✓ create Vault (3587ms) Performance fees delayed Vault ✓ setup vault fixture (2810ms) ✓ create vault (1354ms) ✓ can only deposit after start time (1074ms) ✓ setup fee collector and performance fee ✓ deposits after start time (112ms) ✓ invest and redeem (292ms) Ondo metadata ✓ has a name ✓ has a symbol balanceOf ✓ grants to initial account delegateBySig ✓ reverts if the signatory is invalid (565ms) ✓ reverts if the nonce is bad ✓ reverts if the signature has expired ✓ delegates on behalf of the signatory numCheckpoints ✓ returns the number of checkpoints for a delegate (114ms) Ondo transfer disabled ✓ transfer reverts when transfers are disabled ✓ account with owner permission can transfer ✓ transferAllowed works correctly Registry ✓ grant roles ✓ register contracts Rescue functions pause and rescue asset and LP tokens ✓ doesn't allow rescuing tokens outside of pause mode ✓ pauses and freezes Vault functions (123ms) ✓ rescue tokens (72ms) ✓ stops the pause and restores functionality test reverts ✓ reverts (1164ms) RolloverVault basic round ✓ create pool (4907ms) ✓ revert: create rollover with invalid vault id ✓ revert: create rollver with invalid start time (1027ms) ✓ sucess: create rollover (3977ms) ✓ success: deposit senior asset (263ms) ✓ success: deposit junior asset (264ms) ✓ revert: deposit with invalid rollover id ✓ revert: deposit exceeds senior user cap (85ms) ✓ revert: add vault with invalid tranche assets (1108ms) ✓ revert: add vault with invalid start time (1036ms) ✓ success: adds another Vault to rollover tip (1112ms) ✓ success: migrate (286ms) round with single deposit ✓ create pool (3123ms) ✓ revert: create rollover with invalid vault id ✓ revert: create rollver with invalid start time (975ms) ✓ sucess: create rollover (2996ms) ✓ success: single deposit (95ms) ✓ success: deposit senior asset (263ms) ✓ success: deposit junior asset (264ms) ✓ revert: deposit with invalid rollover id ✓ revert: deposit exceeds senior user cap (77ms) ✓ revert: add vault with invalid tranche assets (1014ms) ✓ revert: add vault with invalid start time (1097ms) ✓ success: adds another Vault to rollover tip (1131ms) ✓ success: migrate (289ms) round with claim ✓ create pool (3067ms) ✓ revert: create rollover with invalid vault id ✓ revert: create rollver with invalid start time (965ms) ✓ sucess: create rollover (4968ms) ✓ success: single deposit (92ms) ✓ success: single deposit (89ms) ✓ success: deposit senior asset (265ms) ✓ success: deposit junior asset (268ms) ✓ revert: deposit with invalid rollover id ✓ revert: deposit exceeds senior user cap (82ms) ✓ revert: add vault with invalid tranche assets (1014ms) ✓ revert: add vault with invalid start time (2004ms) ✓ success: adds another Vault to rollover tip (1099ms) ✓ success: migrate (282ms) ✓ success: claim user tokens and excess (57ms) ✓ success: claim user tokens and excess (55ms) round with withdraw ✓ create pool (3166ms) ✓ revert: create rollover with invalid vault id ✓ revert: create rollver with invalid start time (967ms) ✓ sucess: create rollover (1976ms) ✓ success: single deposit (91ms) ✓ success: single deposit (89ms) ✓ success: deposit senior asset (273ms) ✓ success: deposit junior asset (266ms) ✓ revert: deposit with invalid rollover id ✓ revert: deposit exceeds senior user cap (77ms) ✓ revert: add vault with invalid tranche assets (2070ms) ✓ revert: add vault with invalid start time (1120ms) ✓ success: adds another Vault to rollover tip (1201ms) ✓ success: migrate (278ms) ✓ revert: withdraw zero amount ✓ revert: withdraw more than shares (71ms) ✓ success: withdraw (124ms) ✓ revert: withdraw zero amount ✓ revert: withdraw more than shares (39ms) ✓ success: withdraw (119ms) round with depositLp ✓ create pool (3524ms) ✓ revert: create rollover with invalid vault id (99ms) ✓ revert: create rollver with invalid start time (1089ms) ✓ sucess: create rollover (2042ms) ✓ success: single deposit (88ms) ✓ success: single deposit (91ms) ✓ success: deposit senior asset (270ms) ✓ success: deposit junior asset (267ms) ✓ revert: deposit with invalid rollover id ✓ revert: deposit exceeds senior user cap (77ms) ✓ revert: add vault with invalid tranche assets (990ms) ✓ revert: add vault with invalid start time (1023ms) ✓ success: adds another Vault to rollover tip (1084ms) ✓ success: migrate (274ms) ✓ revert: withdraw zero amount ✓ revert: withdraw more than shares ✓ success: withdraw (119ms) ✓ revert: withdraw zero amount ✓ revert: withdraw more than shares ✓ success: withdraw (114ms) ✓ success: deposit LP tokens mid-duration with signer 7 (674ms) round with withdrawLp ✓ create pool (3072ms) ✓ revert: create rollover with invalid vault id ✓ revert: create rollver with invalid start time (2013ms) ✓ sucess: create rollover (2028ms) ✓ success: single deposit (83ms) ✓ success: single deposit (92ms) ✓ success: deposit senior asset (267ms) ✓ success: deposit junior asset (267ms) ✓ revert: deposit with invalid rollover id ✓ revert: deposit exceeds senior user cap (74ms) ✓ revert: add vault with invalid tranche assets (997ms) ✓ revert: add vault with invalid start time (1038ms) ✓ success: adds another Vault to rollover tip (1098ms) ✓ success: migrate (276ms) ✓ revert: withdraw zero amount ✓ revert: withdraw more than shares (40ms) ✓ success: withdraw (113ms) ✓ revert: withdraw zero amount ✓ revert: withdraw more than shares ✓ success: withdraw (119ms) ✓ success: deposit LP tokens mid-duration with signer 7 (694ms) ✓ success: deposit LP tokens mid-duration with signer 8 (693ms) ✓ success: withdraw LP mid-duration with signer 7 (221ms) ✓ success: withdraw LP mid-duration with signer 8 (225ms) deposit after claim ✓ create pool (5586ms) ✓ revert: create rollover with invalid vault id ✓ revert: create rollver with invalid start time (980ms) ✓ sucess: create rollover (1985ms) ✓ success: single deposit (92ms) ✓ success: single deposit (88ms) ✓ success: deposit senior asset (271ms) ✓ success: deposit junior asset (268ms) ✓ revert: deposit with invalid rollover id ✓ revert: deposit exceeds senior user cap (73ms) ✓ revert: add vault with invalid tranche assets (1000ms) ✓ revert: add vault with invalid start time (1007ms) ✓ success: adds another Vault to rollover tip (1066ms) ✓ success: migrate (277ms) ✓ success: claim user tokens and excess (50ms) ✓ success: claim user tokens and excess (53ms) ✓ success: single deposit (88ms) ✓ success: single deposit (91ms) ✓ success: deposit senior asset (313ms) ✓ success: deposit junior asset (297ms) ✓ revert: deposit with invalid rollover id ✓ revert: deposit exceeds senior user cap (79ms) ✓ revert: add vault with invalid tranche assets (994ms) ✓ revert: add vault with invalid start time (1000ms) ✓ success: adds another Vault to rollover tip (1089ms) ✓ success: migrate (638ms) ✓ success: claim user tokens and excess (271ms) ✓ success: claim user tokens and excess (55ms) StakingPools ✓ should set correct state variables (442ms) ✓ should allow emergency withdraw (328ms) ✓ should give out ondos only after farming time (2036ms) ✓ should not distribute ONDOs if no one deposit (1136ms) ✓ should distribute ondos properly for each staker (2475ms) ✓ should give proper ONDOs allocation to each pool (1578ms) ✓ should stop giving bonus ONDOs after the bonus period ends (2079ms) ✓ should track minimumOndoRequiredBalance properly (1725ms) SushiStrategyLP ✓ pool add and update reverts (13238ms) batchCreate ✓ create Vault: sell senior for leveraged junior returns (1013ms) ✓ create Vault: sell all junior to partially cover senior (993ms) ✓ create Vault: sell some junior to cover senior (1050ms) batchDeposit ✓ deposit senior asset: sell senior for leveraged junior returns (143ms) ✓ deposit junior asset: sell senior for leveraged junior returns (146ms) ✓ deposit senior asset: sell all junior to partially cover senior (145ms) ✓ deposit junior asset: sell all junior to partially cover senior (137ms) ✓ deposit senior asset: sell some junior to cover senior (228ms) ✓ deposit junior asset: sell some junior to cover senior (505ms) increase time ✓ increase time batchInvest ✓ invest assets: sell senior for leveraged junior returns (7377ms) ✓ invest assets: sell all junior to partially cover senior (769ms) ✓ invest assets: sell some junior to cover senior (353ms) increase time ✓ increase time batchMidDeposit ✓ deposit LP tokens mid-duration with signer 4: sell senior for leveraged junior returns (1256ms) ✓ deposit LP tokens mid-duration with signer 4: sell all junior to partially cover senior (734ms) ✓ deposit LP tokens mid-duration with signer 4: sell some junior to cover senior (742ms) batchMidDeposit ✓ deposit LP tokens mid-duration with signer 5: sell senior for leveraged junior returns (741ms) ✓ deposit LP tokens mid-duration with signer 5: sell all junior to partially cover senior (744ms) ✓ deposit LP tokens mid-duration with signer 5: sell some junior to cover senior (738ms) increase time ✓ increase time batchHarvest ✓ harvest rewards: sell senior for leveraged junior returns (265ms) ✓ harvest rewards: sell all junior to partially cover senior (258ms) ✓ harvest rewards: sell some junior to cover senior (267ms) batchMidWithdraw ✓ withdraw LP mid-duration with signer 4: sell senior for leveraged junior returns (180ms) ✓ withdraw LP mid-duration with signer 4: sell all junior to partially cover senior (175ms) ✓ withdraw LP mid-duration with signer 4: sell some junior to cover senior (170ms) batchMidDeposit ✓ deposit LP tokens mid-duration with signer 6: sell senior for leveraged junior returns (744ms) ✓ deposit LP tokens mid-duration with signer 6: sell all junior to partially cover senior (732ms) ✓ deposit LP tokens mid-duration with signer 6: sell some junior to cover senior (737ms) batchHarvest ✓ harvest rewards: sell senior for leveraged junior returns (257ms) ✓ harvest rewards: sell all junior to partially cover senior (265ms) ✓ harvest rewards: sell some junior to cover senior (434ms) increase time ✓ increase time batchClaim ✓ claim tranche tokens: sell senior for leveraged junior returns (405ms) ✓ claim tranche tokens: sell all junior to partially cover senior (172ms) ✓ claim tranche tokens: sell some junior to cover senior (183ms) redeem and withdrawal: sell senior for leveraged junior returns ✓ redeem LP after fee accrual (508ms) ✓ withdraw received amounts (554ms) redeem and withdrawal: sell all junior to partially cover senior ✓ redeem LP after fee accrual (500ms) ✓ withdraw received amounts (536ms) redeem and withdrawal: sell some junior to cover ✓ redeem LP after fee accrual (487ms) ✓ withdraw received amounts (572ms) final sanity check ✓ pool totallp and totalshares is zero works with sushi as token in pair being farmed batchCreate ✓ create Vault: sell senior for leveraged junior returns (1082ms) ✓ create Vault: sell all junior to partially cover senior (985ms) ✓ create Vault: sell some junior to cover senior (1047ms) batchDeposit ✓ deposit senior asset: sell senior for leveraged junior returns (2496ms) ✓ deposit junior asset: sell senior for leveraged junior returns (144ms) ✓ deposit senior asset: sell all junior to partially cover senior (107ms) ✓ deposit junior asset: sell all junior to partially cover senior (137ms) ✓ deposit senior asset: sell some junior to cover senior (106ms) ✓ deposit junior asset: sell some junior to cover senior (149ms) increase time ✓ increase time batchInvest ✓ invest assets: sell senior for leveraged junior returns (1032ms) ✓ invest assets: sell all junior to partially cover senior (324ms) ✓ invest assets: sell some junior to cover senior (326ms) increase time ✓ increase time batchMidDeposit ✓ deposit LP tokens mid-duration with signer 4: sell senior for leveraged junior returns (732ms) ✓ deposit LP tokens mid-duration with signer 4: sell all junior to partially cover senior (724ms) ✓ deposit LP tokens mid-duration with signer 4: sell some junior to cover senior (734ms) batchMidDeposit ✓ deposit LP tokens mid-duration with signer 5: sell senior for leveraged junior returns (723ms) ✓ deposit LP tokens mid-duration with signer 5: sell all junior to partially cover senior (734ms) ✓ deposit LP tokens mid-duration with signer 5: sell some junior to cover senior (732ms) increase time ✓ increase time batchHarvest ✓ harvest rewards: sell senior for leveraged junior returns (228ms) ✓ harvest rewards: sell all junior to partially cover senior (483ms) ✓ harvest rewards: sell some junior to cover senior (406ms) batchMidWithdraw ✓ withdraw LP mid-duration with signer 4: sell senior for leveraged junior returns (178ms) ✓ withdraw LP mid-duration with signer 4: sell all junior to partially cover senior (171ms) ✓ withdraw LP mid-duration with signer 4: sell some junior to cover senior (170ms) batchMidDeposit ✓ deposit LP tokens mid-duration with signer 6: sell senior for leveraged junior returns (720ms) ✓ deposit LP tokens mid-duration with signer 6: sell all junior to partially cover senior (727ms) ✓ deposit LP tokens mid-duration with signer 6: sell some junior to cover senior (725ms) batchHarvest ✓ harvest rewards: sell senior for leveraged junior returns (236ms) ✓ harvest rewards: sell all junior to partially cover senior (226ms) ✓ harvest rewards: sell some junior to cover senior (229ms) increase time ✓ increase time batchClaim ✓ claim tranche tokens: sell senior for leveraged junior returns (175ms) ✓ claim tranche tokens: sell all junior to partially cover senior (166ms) ✓ claim tranche tokens: sell some junior to cover senior (189ms) redeem and withdraw ✓ redeem LP after fee accrual (4314ms) SushiStakingV2Strategy - Alchemix helper alchemix vault lifecycle ✓ get assets (312ms) ✓ add pool (41ms) ✓ create vaults (2513ms) ✓ deposit assets and fast-forward (6346ms) ✓ invest ALCX/ETH vault (8542ms) ✓ invest ETH/ALCX vault (886ms) ✓ harvest (371ms) ✓ harvest (372ms) ✓ harvest (384ms) ✓ harvest (367ms) ✓ harvest (375ms) ✓ harvest (381ms) ✓ redeem ALCX/ETH vault (1600ms) ✓ redeem ETH/ALCX vault (214ms) SushiStakingV2Strategy - WETH-ALCX helper 6) "before all" hook in "SushiStakingV2Strategy - WETH-ALCX helper" SushiStakingV2Strategy - WETH-BIT multiple vaults WETH-BIT - invest first vault 7) "before all" hook: Setup for "should allow registry strategist to create pool in the strategy" SushiStakingV2Strategy - WETH-BIT rescue from all pair WETH-BIT - deposit 8) "before all" hook: Setup for "should allow registry strategist to create pool in the strategy" SushiStakingV2Strategy - WETH-BIT helper 9) "before all" hook in "SushiStakingV2Strategy - WETH-BIT helper" SushiStakingV2Strategy - ETH-YGG-JR-LOSE-ALL helper 10) "before all" hook in "SushiStakingV2Strategy - ETH-YGG-JR-LOSE-ALL helper" SushiStakingV2Strategy - ETH-YGG helper 11) "before all" hook in "SushiStakingV2Strategy - ETH-YGG helper" TrancheToken ✓ spin up tranche tokens on Vault creation (1001ms) ✓ deposit base assets during Deposit phase (145ms) ✓ claim tokens only after investment (236ms) ✓ approve and transferFrom (38ms) Uni ✓ test create mock (4547ms) ✓ test uniPull (650ms) BondStrategy - USDC-BOND helper 12) "before all" hook in "BondStrategy - USDC-BOND helper" BondStrategy - USDC-BOND helper 13) "before all" hook in "BondStrategy - USDC-BOND helper" AllPairVault delayed Vault ✓ setup vault fixture (541ms) ✓ create vault (1030ms) ✓ can only deposit after start time (1054ms) ✓ can get multiple vaults back from getVault (2899ms) ✓ deposits after start time (100ms) ✓ deposits exceed user cap ✓ deposits exceed tranche cap (159ms) ✓ can't deposit after investment withdraw midterm LP deposit ✓ setup vault fixture (2253ms) ✓ create vault (2244ms) ✓ deposit senior asset (173ms) ✓ deposit junior asset (170ms) ✓ deposits as expected ✓ cannot invest too early ✓ invest assets (160ms) ✓ can't deposit or withdraw midterm unless tranche tokens are enabled ✓ deposit LP tokens mid-duration with signer 7 (460ms) ✓ withdraws as expected after depositing LP without claiming (322ms) ✓ withdraw received amounts (268ms) sell senior for leveraged junior returns ✓ setup vault fixture (535ms) ✓ create vault (2080ms) ✓ deposit senior asset (171ms) ✓ deposit junior asset (171ms) ✓ deposits as expected ✓ cannot invest too early ✓ gets Vault by tranche token addresses ✓ gets all Vaults ✓ invest assets (152ms) ✓ claim tranche tokens and excess (256ms) ✓ withdraw LP mid-duration from original deposits (359ms) ✓ deposit LP tokens mid-duration with signer 6 (442ms) ✓ deposit LP tokens mid-duration with signer 7 (469ms) ✓ withdraw LP mid-duration with signer 6 (111ms) ✓ withdraw LP mid-duration with signer 7 (111ms) ✓ redeem LP after fee accrual (312ms) ✓ withdraw received amounts (423ms) sell all junior to partially cover senior ✓ setup vault fixture (2588ms) ✓ create vault (1106ms) ✓ deposit senior asset (173ms) ✓ deposit junior asset (165ms) ✓ deposits as expected ✓ cannot invest too early ✓ invest assets (152ms) ✓ claim tranche tokens and excess (262ms) ✓ withdraw LP mid-duration from original deposits (359ms) ✓ deposit LP tokens mid-duration with signer 6 (437ms) ✓ deposit LP tokens mid-duration with signer 7 (470ms) ✓ withdraw LP mid-duration with signer 6 (108ms) ✓ withdraw LP mid-duration with signer 7 (108ms) ✓ redeem LP after fee accrual (282ms) ✓ withdraw received amounts (422ms) sell some junior to cover senior ✓ setup vault fixture (3033ms) ✓ create vault (1201ms) ✓ deposit senior asset (173ms) ✓ deposit junior asset (175ms) ✓ deposits as expected ✓ cannot invest too early ✓ invest assets (154ms) ✓ claim tranche tokens and excess (258ms) ✓ withdraw LP mid-duration from original deposits (356ms) ✓ deposit LP tokens mid-duration with signer 6 (450ms) ✓ deposit LP tokens mid-duration with signer 7 (469ms) ✓ withdraw LP mid-duration with signer 6 (113ms) ✓ withdraw LP mid-duration with signer 7 (109ms) ✓ redeem LP after fee accrual (275ms) ✓ withdraw received amounts (427ms) 411 passing (8m) 13 failing 1) masterchefv2 dual incentive pool mcv2 vault lifecycle get LP from the sushiswap pool and deposit: AssertionError: Expected "2" to be equal 1 at Context. (test/alchemix.spec.ts:273:38) at runMicrotasks () at processTicksAndRejections (internal/process/task\_queues.js:93:5) at runNextTicks (internal/process/task\_queues.js:62:3) at listOnTimeout (internal/timers.js:523:9) at processTimers (internal/timers.js:497:7) 2) masterchefv2 dual incentive pool mcv2 vault lifecycle withdraw LP from ALCX/ETH vault: AssertionError: Expected "2" to be equal 1 at Context. (test/alchemix.spec.ts:306:39) at runMicrotasks () at processTicksAndRejections (internal/process/task\_queues.js:93:5) at runNextTicks (internal/process/task\_queues.js:62:3) at listOnTimeout (internal/timers.js:523:9) at processTimers (internal/timers.js:497:7) 3) masterchefv2 dual incentive pool mcv2 vault lifecycle deposit LP in ALCX/ETH vault: AssertionError: Expected "2" to be equal 1 at Context. (test/alchemix.spec.ts:317:38) at runMicrotasks () at processTicksAndRejections (internal/process/task\_queues.js:93:5) at runNextTicks (internal/process/task\_queues.js:62:3) at listOnTimeout (internal/timers.js:523:9) at processTimers (internal/timers.js:497:7) 4) EdenStrategy - WETH-EDEN helper "before all" hook in "EdenStrategy - WETH-EDEN helper": Error: call revert exception (method="decimals()", errorArgs=null, errorName=null, errorSignature=null, reason=null, code=CALL\_EXCEPTION, version=abi/5.4.1) at Logger.makeError (node\_modules/@ethersproject/logger/src.ts/index.ts:225:28) at Logger.throwError (node\_modules/@ethersproject/logger/src.ts/index.ts:237:20) at Interface.decodeFunctionResult (node\_modules/@ethersproject/abi/src.ts/interface.ts:425:23) at Contract. (node\_modules/@ethersproject/contracts/src.ts/index.ts:332:44) at step (node\_modules/@ethersproject/contracts/lib/index.js:48:23) at Object.next (node\_modules/@ethersproject/contracts/lib/index.js:29:53) at fulfilled (node\_modules/@ethersproject/contracts/lib/index.js:20:58) 5) BondStrategy - USDC-BOND helper USDC-BOND - deployment validation USDC-BOND - vault lifecycle USDC-BOND vault behaviour - invest USDC-BOND vault behaviour - harvest and redeem USDC-BOND mid term deposits should allow investors to claim junior tranche tokens and excess: AssertionError: expected undefined to equal 0 at Context. (test/behaviour/auniswap/vaultMidtermdeposits.ts:170:48) at runMicrotasks () at processTicksAndRejections (internal/process/task\_queues.js:93:5) at runNextTicks (internal/process/task\_queues.js:62:3) at listOnTimeout (internal/timers.js:523:9) at processTimers (internal/timers.js:497:7) 6) SushiStakingV2Strategy - WETH-ALCX helper "before all" hook in "SushiStakingV2Strategy - WETH-ALCX helper": Error: VM Exception while processing transaction: reverted with reason string 'UniswapV2Router: EXCESSIVE\_INPUT\_AMOUNT' at . (0xd9e1ce17f2641f24ae83637ab66a2cca9c378b9f) at runMicrotasks () at processTicksAndRejections (internal/process/task\_queues.js:93:5) at runNextTicks (internal/process/task\_queues.js:62:3) at listOnTimeout (internal/timers.js:523:9) at processTimers (internal/timers.js:497:7) at HardhatNode.\_mineBlockWithPendingTxs (node\_modules/hardhat/src/internal/hardhat-network/provider/node.ts:1582:23) at HardhatNode.mineBlock (node\_modules/hardhat/src/internal/hardhat-network/provider/node.ts:435:16) 7) SushiStakingV2Strategy - WETH-BIT multiple vaults WETH-BIT - invest first vault "before all" hook: Setup for "should allow registry strategist to create pool in the strategy": Error: Transaction reverted without a reason string at . (0xd9e1ce17f2641f24ae83637ab66a2cca9c378b9f) at HardhatNode.\_mineBlockWithPendingTxs (node\_modules/hardhat/src/internal/hardhat-network/provider/node.ts:1582:23) at HardhatNode.mineBlock (node\_modules/hardhat/src/internal/hardhat-network/provider/node.ts:435:16) at EthModule.\_sendTransactionAndReturnHash (node\_modules/hardhat/src/internal/hardhat-network/provider/modules/eth.ts:1494:18) at HardhatNetworkProvider.request (node\_modules/hardhat/src/internal/hardhat-network/provider/provider.ts:108:18) at EthersProviderWrapper.send (node\_modules/@nomiclabs/hardhat-ethers/src/internal/ethers-provider-wrapper.ts:13:20) 8) SushiStakingV2Strategy - WETH-BIT rescue from all pair WETH-BIT - deposit "before all" hook: Setup for "should allow registry strategist to create pool in the strategy": Error: Transaction reverted without a reason string at . (0xd9e1ce17f2641f24ae83637ab66a2cca9c378b9f) at runMicrotasks () at processTicksAndRejections (internal/process/task\_queues.js:93:5) at runNextTicks (internal/process/task\_queues.js:62:3) at listOnTimeout (internal/timers.js:523:9) at processTimers (internal/timers.js:497:7) at HardhatNode.\_mineBlockWithPendingTxs (node\_modules/hardhat/src/internal/hardhat-network/provider/node.ts:1582:23) at HardhatNode.mineBlock (node\_modules/hardhat/src/internal/hardhat-network/provider/node.ts:435:16) 9) SushiStakingV2Strategy - WETH-BIT helper "before all" hook in "SushiStakingV2Strategy - WETH-BIT helper": Error: Transaction reverted without a reason string at . (0xd9e1ce17f2641f24ae83637ab66a2cca9c378b9f) at runMicrotasks () at processTicksAndRejections (internal/process/task\_queues.js:93:5) at runNextTicks (internal/process/task\_queues.js:62:3) at listOnTimeout (internal/timers.js:523:9) at processTimers (internal/timers.js:497:7) at HardhatNode.\_mineBlockWithPendingTxs (node\_modules/hardhat/src/internal/hardhat-network/provider/node.ts:1582:23) at HardhatNode.mineBlock (node\_modules/hardhat/src/internal/hardhat-network/provider/node.ts:435:16) 10) SushiStakingV2Strategy - ETH-YGG-JR-LOSE-ALL helper "before all" hook in "SushiStakingV2Strategy - ETH-YGG-JR-LOSE-ALL helper": Error: call revert exception (method="decimals()", errorArgs=null, errorName=null, errorSignature=null, reason=null, code=CALL\_EXCEPTION, version=abi/5.4.1) at Logger.makeError (node\_modules/@ethersproject/logger/src.ts/index.ts:225:28) at Logger.throwError (node\_modules/@ethersproject/logger/src.ts/index.ts:237:20) at Interface.decodeFunctionResult (node\_modules/@ethersproject/abi/src.ts/interface.ts:425:23) at Contract. (node\_modules/@ethersproject/contracts/src.ts/index.ts:332:44) at step (node\_modules/@ethersproject/contracts/lib/index.js:48:23) at Object.next (node\_modules/@ethersproject/contracts/lib/index.js:29:53) at fulfilled (node\_modules/@ethersproject/contracts/lib/index.js:20:58) 11) SushiStakingV2Strategy - ETH-YGG helper "before all" hook in "SushiStakingV2Strategy - ETH-YGG helper": Error: call revert exception (method="decimals()", errorArgs=null, errorName=null, errorSignature=null, reason=null, code=CALL\_EXCEPTION, version=abi/5.4.1) at Logger.makeError (node\_modules/@ethersproject/logger/src.ts/index.ts:225:28) at Logger.throwError (node\_modules/@ethersproject/logger/src.ts/index.ts:237:20) at Interface.decodeFunctionResult (node\_modules/@ethersproject/abi/src.ts/interface.ts:425:23) at Contract. (node\_modules/@ethersproject/contracts/src.ts/index.ts:332:44) at step (node\_modules/@ethersproject/contracts/lib/index.js:48:23) at Object.next (node\_modules/@ethersproject/contracts/lib/index.js:29:53) at fulfilled (node\_modules/@ethersproject/contracts/lib/index.js:20:58) at runMicrotasks () at processTicksAndRejections (internal/process/task\_queues.js:93:5) at runNextTicks (internal/process/task\_queues.js:62:3) 12) BondStrategy - USDC-BOND helper "before all" hook in "BondStrategy - USDC-BOND helper": Error: VM Exception while processing transaction: reverted with reason string 'UniswapV2Router: EXCESSIVE\_INPUT\_AMOUNT' at . (0x7a250d5630b4cf539739df2c5dacb4c659f2488d) at runMicrotasks () at processTicksAndRejections (internal/process/task\_queues.js:93:5) at runNextTicks (internal/process/task\_queues.js:62:3) at listOnTimeout (internal/timers.js:523:9) at processTimers (internal/timers.js:497:7) at HardhatNode.\_mineBlockWithPendingTxs (node\_modules/hardhat/src/internal/hardhat-network/provider/node.ts:1582:23) at HardhatNode.mineBlock (node\_modules/hardhat/src/internal/hardhat-network/provider/node.ts:435:16) 13) BondStrategy - USDC-BOND helper "before all" hook in "BondStrategy - USDC-BOND helper": Error: VM Exception while processing transaction: reverted with reason string 'UniswapV2Router: EXCESSIVE\_INPUT\_AMOUNT' at . (0x7a250d5630b4cf539739df2c5dacb4c659f2488d) at runMicrotasks () at processTicksAndRejections (internal/process/task\_queues.js:93:5) at runNextTicks (internal/process/task\_queues.js:62:3) at listOnTimeout (internal/timers.js:523:9) at processTimers (internal/timers.js:497:7) at HardhatNode.\_mineBlockWithPendingTxs (node\_modules/hardhat/src/internal/hardhat-network/provider/node.ts:1582:23) at HardhatNode.mineBlock (node\_modules/hardhat/src/internal/hardhat-network/provider/node.ts:435:16) Code Coverage Some tests are failing and thus it is not possible to reliably evaluate the code coverage at this stage. File% Stmts% Branch% Funcs% LinesUncovered Lines contracts/94.3671.9490.294.29 AllPairVault.sol96.6972.1297.7896.75... 9,1170,1171 OndoRegistryClient.sol100100100100 OndoRegistryClientInitializable.sol92.8662.585.7193.3351 Registry.sol64.295066.6765.52... 147,148,160 RolloverVault.sol96.6880.310096.7... 681,686,735 SampleFeeCollector.sol10050100100 TrancheToken.sol71.432563.6468.75... 100,109,118 contracts/dao/0000 GovernorBravoDelegate.sol0000... 583,584,587 GovernorBravoDelegator.sol0000... 66,67,81,83 GovernorBravoInterfaces.sol100100100100 SafeMath.sol0000... 184,203,204 Timelock.sol0000... 186,188,193 contracts/interfaces/100100100100 IFeeCollector.sol100100100100 IPairVault.sol100100100100 IRegistry.sol100100100100 IRollover.sol100100100100 IStrategy.sol100100100100 ITrancheToken.sol100100100100 IUserTriggeredReward.sol100100100100 IWETH.sol100100100100 contracts/libraries/100100100100 OndoLibrary.sol100100100100 contracts/strategies/67.3743.9567.1267.79 ASushiswapStrategy.sol0000... 445,446,447 AUniswapStrategy.sol65.5639.2963.6466.67... 475,476,484 AlchemixLPStrategy.sol95.3956.5210095.45... 473,505,506 BasePairLPStrategy.sol77.785010078.9585,86,87,88 BondStrategy.sol10077.78100100 DopexStrategy.sol0000... 186,190,192 EdenStrategy.sol21.282512.521.28... 179,184,186 File% Stmts% Branch% Funcs% LinesUncovered Lines SushiStakingV2Strategy.sol65.5741.8969.5766.19... 816,817,818 SushiStrategyLP.sol10066.67100100 UniswapStrategy.sol91.6768.7593.3391.8... 373,374,375 contracts/strategies/helpers/702566.6770 AlchemixUserReward.sol702566.677030,31,32 contracts/test/40.3810036.8440.38 ERC20Mock.sol40100754018,20,21 ForceSendEth.sol100100100100 Imports.sol1001000100 MockRewarder.sol010000... 37,38,39,40 TestRewardHelper.sol01000011,15,19,20 UniPull.sol47.061005047.06... 43,44,45,46 contracts/test/barnbridge/100100100100 MockStaking.sol100100100100 contracts/tokens/74.1654.1782.3574.86 Ondo.sol58.9547.7376.1960.42... 292,295,379 StakingPools.sol91.5764.2992.3191.57... 144,259,260 contracts/vendor/abdk/10010000 ABDKMathQuad.sol10010000... 2,1664,1677 contracts/vendor/alchemix/100100100100 IStakingPools.sol100100100100 contracts/vendor/barnbridge/100100100100 Staking.sol100100100100 YieldFarmLP.sol100100100100 contracts/vendor/dopex/100100100100 IStakingRewards.sol100100100100 contracts/vendor/eden/100100100100 IRewardsManager.sol100100100100 contracts/vendor/sushiswap/100100100100 IMasterChef.sol100100100100 IMasterChefV2.sol100100100100 IRewarder.sol100100100100 ISushiBar.sol100100100100 contracts/vendor/uniswap/58.822562.558.82 SushiSwapLibrary.sol58.822562.558.82... 129,130,132 UniswapV2Library.sol58.822562.558.82... 129,130,132 All files67.7143.2160.3567.26 Appendix File Signatures The following are the SHA-256 hashes of the reviewed files. A file with a different SHA-256 hash has been modified, intentionally or otherwise, after the security review. You are cautioned that a different SHA-256 hash could be (but is not necessarily) an indication of a changed condition or potential vulnerability that was not within the scope of the review. Contracts b7fb3be8abcaf9350d8ff0f6cbfd2e54bceb306d7287c0eb61f388a33ea207d9./StakingPools.sol d0acfa5eadf123ed7066569a6c9db9d76d97053458d0728af517e27319fd86bd./Ondo.sol 262c395ddf87a2a478930445380bc533ac0857d6f4724c891767e17c0fef1b2f./OndoLibrary.sol 01343f283af0ea51d215feefa79c5a59b5e4432f29a2e6907fba1adf2b404a4e./TrancheToken.sol 6c263bde545659f48051814be385874dca90acc11a4bcdbfa18f2beba20e5ac0./SampleFeeCollector.sol 365c205a33be504ee56729d962fadffbdf7c5c82f9d7dfbc94ac68353441e1a7./RolloverVault.sol 491d582b501cae87b72f58c2f5b98ee7435d1308e1afcd4b386e306815578f82./Registry.sol a4ce7c250d5ca36d16e03f16f659424a0434dfa1c6c7241e407fd1e1ccc702b8./AllPairVault.sol 176a90318116f4051fe0d543d20aa192502a8dbd783d7fe1cb865f94ee110909./OndoRegistryClientInitializable.sol 15e64cc312a3d7ebaa2cbd4ad30bf15f380616bbe80e2a92e32d99828f142c5c./OndoRegistryClient.sol fe9fad57c5ddee134040f86e9c5434e0c337a138fff20ead12b1806fece3dc75./AlchemixUserReward.sol 9def31e71e84f9b14ba45290bb3dd9d8293c29f6d893bae1c5ddede80b7d7081./UniswapStrategy.sol e2921400d0d44176395bfafa878892af391badad3a12a927104c76e95bbffb8b./SushiStrategyLP.sol fc7153b62f538e370f8bc4eb0a5524cb6e76c05f1fb870da8e7d02708f2378b7./SushiStakingV2Strategy.sol 4ffa161e757a3a0374936d78d47b7ce4b202c9db43c7fdb726a6ad852dc20867./EdenStrategy.sol f940caa491e39d43818e653064d89f2199bc194265d1fe2bf66032627af3cc0c./DopexStrategy.sol b28ed5920f4e4a05dab38f4385a607a7a2f33d5da10699fd9eedd23da7a42659./BondStrategy.sol 5f27f6caa1f4b8a5ddd9f4dde0810feed79467782128be117755c27b4c2f59c9./AlchemixLPStrategy.sol 6193076e3f6fb2cb878b68310710618f2123250ed77b5fe9d4cd86f4aa066ac6./BasePairLPStrategy.sol 5e4bfc31dbbf3a9e9cbef91a76a3aec6efa4a6ee89cce28cf1e49e63ce0011b4./AUniswapStrategy.sol 765410b533d5a99c57aea49ffbefb8eb698b16df66095513a06b46be0d966843./ASushiswapStrategy.sol 8e487d567f6814e03d5c7a7d5cd94afb9573ee10bf8b8cb38b4e1e4ceb0205c2./QuickSwapLibrary.sol 46489c93eff8908a663110b3d16da8e8e1681d69d0d786b1df2e8003ccce25a8./QuickswapStrategyLP.sol 4d7d9fe5b5918e64550ff7b991dca72f86dadc491ae5b76dbf210ee8c092f86b./PancakeSwapLibrary.sol 6655f3a6f1563db0fd3c12e364eae9f7ffd22a7bbb9ea403875ff1f2dd8b6453./PancakeStrategyLP.sol 311019158d3c5fc17c24462df46332f7e93c82f391142b34b6b08758857a0113./PancakeStrategy.sol 1f9a1232376a48efaa33173bde866ba332d4034a556712e6243c41ab4bcd6888./contracts/RolloverVault.sol 15e64cc312a3d7ebaa2cbd4ad30bf15f380616bbe80e2a92e32d99828f142c5c./contracts/OndoRegistryClient.sol 9c46b41bb23ad9def04afffaa1766fa143b4d4b5c0f011bad6356bfb58de88e5./contracts/Registry.sol aa6972e837edea97fd06e1a81eef4e535c52cb54e0182b041b6fb32b9be63a9b./contracts/AllPairVault.sol e8026853efba0286ab7efadd01b4b4ff3947bf3e7f88cbc094ec91e5916d7088./contracts/TrancheToken.sol b7fb3be8abcaf9350d8ff0f6cbfd2e54bceb306d7287c0eb61f388a33ea207d9./contracts/tokens/StakingPools.sol d0acfa5eadf123ed7066569a6c9db9d76d97053458d0728af517e27319fd86bd./contracts/tokens/Ondo.sol 262c395ddf87a2a478930445380bc533ac0857d6f4724c891767e17c0fef1b2f./contracts/libraries/OndoLibrary.sol 5b5c45cd2d6ab0286484c21e05fb2f92f0d661cece1d7ee43cb9f9839f7331fa./contracts/strategies/UniswapStrategy.sol 765410b533d5a99c57aea49ffbefb8eb698b16df66095513a06b46be0d966843./contracts/strategies/ASushiswapStrategy.sol 05cf5ab589cb58db1cbef3571d65a786c41959a8bc93aeb71142fac371eb1d55./contracts/strategies/BondStrategy.sol 098606fe8f5487482b21f7f00723117d60226d56c52c42f27b10bb9f5d1627f3./contracts/strategies/SushiStakingV2Strategy.sol 5e4bfc31dbbf3a9e9cbef91a76a3aec6efa4a6ee89cce28cf1e49e63ce0011b4./contracts/strategies/AUniswapStrategy.sol 8c278ef208d263d197a1d6c5bd58396e510d1b2065ee583c2a701411e6c8a43f./contracts/strategies/DopexStrategy.sol 6193076e3f6fb2cb878b68310710618f2123250ed77b5fe9d4cd86f4aa066ac6./contracts/strategies/BasePairLPStrategy.sol 50a42214be23c799465893152ec6131eece3745fb95c8a446efb0d3dee2ed5e8./contracts/strategies/AlchemixLPStrategy.sol 7fd125893cfc7b2b5006fc114920ba9a71195e09fda6fb42c9888b22f6e42a93./contracts/strategies/SushiStrategyLP.sol 89d39c13b5c702cc841c126d4ddbad9c1564bc501ae73f61c0f2d922f7c33a2a./contracts/strategies/EdenStrategy.sol 35c9982ba76ec7f3b8deba76861d3307a5774424a2373b20664d89f8217451ba./contracts/strategies/helpers/AlchemixUserReward.sol Tests f53f15453e843ef9d70317f9e0b312615c3457bedb3d558fe949d82d8768f039./test/create2.spec.ts 2adb4b543786993b2cd6e07b2f8e56a480b7b4da4444271f8c1842c29b1e8f36./test/sushi2.spec.weth-ygg.ts e79f5713e8f75fa048c4362c9a12c67bd66ae6b8e67227450dec4a3c4bd89605./test/staking.spec.ts 7700a794145cfd15235ee1743f8fc5c09e4a240b7ea73c7483a52f2e65a15810./test/reverts.spec.ts 8c2e9ca7ea47c012968dc72e4a856f9040ef410435d23a0d7db9c4a33ad4f3b7./test/sushi2.spec.weth-bit-rescue-from-allpair.ts 989e36c091ee53c818598103ffde2c979770f56ca36f5c0adaaaa3efe24b6d71./test/sushi2.spec.weth-ygg-jnrsLose.ts 0193a90e7c513149a5731bc6e5732df679e180a72d5f594216d59f004954ba0e./test/sushi2.spec.weth-bit.ts 19681bfbafe32c7161ea18af32ba8cd8b948e8ab5df161d9e52bd6044a0cd42c./test/uni.spec.usdt-bond-multivaults.ts b0e250667999bf0bed33db084e6a001fd1e6e6b0df3eb38d4ad79537e76e689d./test/uni.spec.usdt-bond-jrs-gain.ts 9ef67da498823f00c0a8a45b8042a6a5ab42455ea8ba3f5be462ffcbe5838124./test/fee.spec.ts 6e4a5170ee1dfb39ee6d0d0f081555034c300ef0209ad5552c9ef405ca687796./test/ondo.spec.ts 632ea85d33b6cf9f011e6e1ef462cb66c2c4965ae44ff082f5ade451ae1f1c0e./test/uni.spec.ts 17afdb8ff44c2183959ead7d20be172a8e6c0a156a27b4445ad8855a4c36894b./test/token.spec.ts a1e740005618534bf1758c6cfe82ae0ff9f1845c9e83c510b880cf28d22fedf7./test/rollover.spec.ts c4c1079f34f3c223e75f07296ec3f604aa612c0930a8c7adeda26c4b6589f095./test/uni.spec.usdt-bond.ts d3c37dba547ba56afbac2045693ec627bfc84ace8b9aee69ffd7d284d3735936./test/sushi2.spec.weth-bit-multiple-vaults.ts 0194112e64af2b47636a5717a770d82de4bbca6ba6e23f263796b75258bf3c53./test/claim.spec.ts ec87cdb2058a3cc3071a4546b55dea0b6b66372dd0414b01e4e606b484e035b1./test/vault.spec.ts 654a1bd43af19f69a41858629489e90a037ff9534dddc427d6c68eb9034b9df4./test/auni.spec.usdt-bond.ts d8d0238f8f2a486e94b822c331e381d943736895bda6dae6ff88be1d9c6b47a8./test/asushi.spec.weth-eden.ts d8502b60cea7501fdc780ae30f8a26da8cddf03cc00bbc1153c5d0c334cc375e./test/registry.spec.ts 91e20259239d37e6cab96e800ac07781d612d95d7ec85964c09e6536e64a329b./test/sushi2.spec.ts 78fb7c7d8a65242a1867edcf91796aae53530290c845712df8c03885c9c077e9./test/alchemix.spec.ts 9c93d37cabeab06ccdb89f72bab7e2c73ef28c261516966ae0c5c1bce8f13cd8./test/sushi-lp.spec.ts 438de978ff6d4cf5452eb6a68917d7a31a47b0ecfc238a0a8d56312a625f76c5./test/rescue.spec.ts 96ef1266ddbe8f0f67e1942d7e8c4946d3be230c6939467cb1a4b805f5c1eaa7./test/rollover.spec-forked.ts 96acb6f7f02998f39f382f5c42d67ecbc3ee467a8561561c1b946c5d59985711./test/sushi2.spec.weth-alcx.ts a120f177affd17ce416947cc181ccd35457854e945122185fc811e7347a3c3a1./test/behaviour/vaultHarvestAndRedeemMultiVaultsSimple.ts f2cead3facc2a0cdb0961a4e63cc177b12003cef76cd9f88db436b0b51d5bd01./test/behaviour/emergencyRescueToSigner.ts adcea2615c31632bb9890e6b1ed19f8343a1c307aff1158e9d6ab47d7e2fcd1a./test/behaviour/vaultMidtermdeposits.ts 28795da284d4b6bf636dee6d1e1b5897cf59f4818c21e37a580ebe29608015cc./test/behaviour/vaultInvestmentLifecycle.ts d38f5b63d71924e6962dfbd332813f4f093e8d0334809e27d5e9767afbcafe38./test/behaviour/vaultInvestmentSimple.ts 7c6b5a1962fedad466b312b4203b9588068806d7a88e4b233082a1edf6c96116./test/behaviour/vaultRollovers.ts 09cb79ef65922fa89a000e7dd641aaf5b91fd1df61599ffce3963926cbf3fbb9./test/behaviour/vaultLifecycle.ts 275d4088de32d9bcdd182ec3cee7c7ebaa0efdf5cdeb0e79d22a95befd69e4c9./test/behaviour/vaultInvestViaCallFunction.ts f10abaa7b7a24e4f7c7f6ff76d93d4d03849a3e92a7d4201f4c8f58e0de7adca./test/behaviour/emergencyRescueToStrategy.ts 9e459bf35587c33097c27e824f702d25c4b2d78af1f8ac2bfedfaaee8611496e./test/behaviour/vaultHarvestAndRedeem.ts 945c6b3ee037a30b17c49fc3f9146934b9789916d3580a84a2735b897c91633b./test/behaviour/auniswap/invest.ts ce5b53b2d5b0e2910a9903c21e6fe9b30eb0464423d4ed6f5083089ff1da037e./test/behaviour/auniswap/vaultMidtermdeposits.ts b7ca16a52a8996ec35280135914c3488f0f9c6a78842f44581a40d0c3b5bf84d./test/behaviour/auniswap/uniStrategySetup.ts 852d50384f83cdf9f93336c33933a8670d784421db7ed0e8ae0b16cdbd6b8d54./test/behaviour/auniswap/vaultLifecycle.ts 9bddd6fb998581bbe7214fdf61b72be384f6bfe566b915bd71ea13d4e1d73341./test/behaviour/auniswap/vaultInvestment.ts b16d1ef54e0054ae8832e0661fb4c72d8723f2ac76b4b543377a2ce606a46bb9./test/behaviour/auniswap/emergencyRescueToStrategy.ts 5851859ffb174551f1144dcf50c5b74025242570018e01aabbde726bd585562c./test/behaviour/auniswap/vaultHarvestAndRedeem.ts 945c6b3ee037a30b17c49fc3f9146934b9789916d3580a84a2735b897c91633b./test/behaviour/asushiswap/invest.ts c2860058dbb342749a7b8ee403a964fe6871837f4fd6fad67d59fa487b197230./test/behaviour/asushiswap/vaultMidtermdeposits.ts 91e9d6df5314e71d3aad744ccef76bcc3e9e7911a7ef24109f2c4f408e7bb54f./test/behaviour/asushiswap/uniStrategySetup.ts 852d50384f83cdf9f93336c33933a8670d784421db7ed0e8ae0b16cdbd6b8d54./test/behaviour/asushiswap/vaultLifecycle.ts 9bddd6fb998581bbe7214fdf61b72be384f6bfe566b915bd71ea13d4e1d73341./test/behaviour/asushiswap/vaultInvestment.ts 55f8ad322bc1ad9b6146eac4a4fbbda73aa8e2ded5e73ef4a818ab8042634ace./test/behaviour/asushiswap/emergencyRescueToStrategy.ts 5851859ffb174551f1144dcf50c5b74025242570018e01aabbde726bd585562c./test/behaviour/asushiswap/vaultHarvestAndRedeem.ts a7d7c451e51bd007c6a9956e2c01c16e4192a95af70684502f275f014604163b./test/behaviour/uniswap/invest.ts e507350f2d10504d6ddad65fb0b85cb4b06f78499b8ef49cd66edc27594982d3./test/behaviour/uniswap/vaultMidtermdeposits.ts 3d16c88e2dc51dd619ef42baab17bc323d35bdea6860036cc379ccd7f8142f82./test/behaviour/uniswap/vaultPathChangesRedeem.ts 4f37b82a75bc131d05c33ab387a883f0ffd004c6264f2c0e04820e9d3961f4e2./test/behaviour/uniswap/multivaultLifecycle.ts 3ece72a24adc556fdba395d2dbca705bfaa47585c74afc82c07d1928a4e13eaa./test/behaviour/uniswap/uniStrategySetup.ts 2ac78115e9513a637c2efecfa06248a3d31b4f084ad68b26a5470ccd3390b1c2./test/behaviour/uniswap/vaultRedeem.ts 65432da3bd3b94a26ee8396205322706aa84c23c455e3fe8d1350923430d9fe2./test/behaviour/uniswap/vaultLifecycle.ts 85397c8642108c2fac2204994d4c3c3f2e6cba40d8247f7fa896852f949e42c4./test/behaviour/uniswap/vaultInvestment.ts 1a657fcdbafda3af377e3e82a13a554b8899f7f49153f8c109c6b9cc9fb0a084./test/behaviour/uniswap/emergencyRescueToStrategy.ts 295e2a0d7763e85150d6eaa8bcf1779b6e5b42e760b0c1f083ce02b105d85657./test/utils/DebugSigner.ts 5db8a0062c5cc308c9114d7bfd4de63a940a3c0cbd0ea278e218d6f56f3aa90b./test/utils/addresses.ts fa43c22f095ba4b2eb52dea637f35cf59bd86ef5599492e889f041e2c3237f56./test/utils/gen-utils.ts 9069b3f8a3a137776ea906d8b81b0a7a0cf9338231b7a4947d98d7648736bb54./test/utils/bignumberhax.ts 6f603be8959b57dd21f708ec298728c27ac43521e19461bedf9a12bb9ae25c0e./test/utils/vault.ts b14c977b9e56be27600fe7f0ec37a64bcc0f0f47e4251645a7844b4bc0b74da9./test/utils/rollover-forkednw.ts 66e8bc2c94fba576664f9b3835e7622f32c416aa20b619e1e6d6b78118992477./test/utils/uni.ts c3d718f6909e8ed75a73b2c4c9416487197d84108a617fda9315afe60f3df5af./test/utils/logger.ts 8cc6c09f8181c159c64257318bbe50cc3a3e0574fdfbeb07a65d12a82659bd28./test/utils/rollover.ts d629e629864f5062bfa441b427ad696853b1b00e644eb632fc9cc93d4d8bdecf./test/utils/getters.ts 95e0919c58dd3dd10cd81597a7a034888902e174046af6e66c269077ddad8810./test/utils/signing.ts Changelog 2021-12-22 - Initial report• 2022-01-25 - Re-audit• About Quantstamp Quantstamp is a Y Combinator-backed company that helps to secure blockchain platforms at scale using computer-aided reasoning tools, with a mission to help boost the adoption of this exponentially growing technology. With over 1000 Google scholar citations and numerous published papers, Quantstamp's team has decades of combined experience in formal verification, static analysis, and software verification. Quantstamp has also developed a protocol to help smart contract developers and projects worldwide to perform cost-effective smart contract security scans. To date, Quantstamp has protected $5B in digital asset risk from hackers and assisted dozens of blockchain projects globally through its white glove security assessment services. As an evangelist of the blockchain ecosystem, Quantstamp assists core infrastructure projects and leading community initiatives such as the Ethereum Community Fund to expedite the adoption of blockchain technology. Quantstamp's collaborations with leading academic institutions such as the National University of Singapore and MIT (Massachusetts Institute of Technology) reflect our commitment to research, development, and enabling world-class blockchain security. Timeliness of content The content contained in the report is current as of the date appearing on the report and is subject to change without notice, unless indicated otherwise by Quantstamp; however, Quantstamp does not guarantee or warrant the accuracy, timeliness, or completeness of any report you access using the internet or other means, and assumes no obligation to update any information following publication. Notice of confidentiality This report, including the content, data, and underlying methodologies, are subject to the confidentiality and feedback provisions in your agreement with Quantstamp. These materials are not to be disclosed, extracted, copied, or distributed except to the extent expressly authorized by Quantstamp. Links to other websites You may, through hypertext or other computer links, gain access to web sites operated by persons other than Quantstamp, Inc. (Quantstamp). Such hyperlinks are provided for your reference and convenience only, and are the exclusive responsibility of such web sites' owners. You agree that Quantstamp are not responsible for the content or operation of such web sites, and that Quantstamp shall have no liability to you or any other person or entity for the use of third-party web sites. Except as described below, a hyperlink from this web site to another web site does not imply or mean that Quantstamp endorses the content on that web site or the operator or operations of that site. You are solely responsible for determining the extent to which you may use any content at any other web sites to which you link from the report. Quantstamp assumes no responsibility for the use of third-party software on the website and shall have no liability whatsoever to any person or entity for the accuracy or completeness of any outcome generated by such software. Disclaimer This report is based on the scope of materials and documentation provided for a limited review at the time provided. Results may not be complete nor inclusive of all vulnerabilities. The review and this report are provided on an as-is, where-is, and as-available basis. You agree that your access and/or use, including but not limited to any associated services, products, protocols, platforms, content, and materials, will be at your sole risk. Blockchain technology remains under development and is subject to unknown risks and flaws. The review does not extend to the compiler layer, or any other areas beyond the programming language, or other programming aspects that could present security risks. A report does not indicate the endorsement of any particular project or team, nor guarantee its security. No third party should rely on the reports in any way, including for the purpose of making any decisions to buy or sell a product, service or any other asset. To the fullest extent permitted by law, we disclaim all warranties, expressed or implied, in connection with this report, its content, and the related services and products and your use thereof, including, without limitation, the implied warranties of merchantability, fitness for a particular purpose, and non-infringement. We do not warrant, endorse, guarantee, or assume responsibility for any product or service advertised or offered by a third party through the product, any open source or third-party software, code, libraries, materials, or information linked to, called by, referenced by or accessible through the report, its content, and the related services and products, any hyperlinked websites, any websites or mobile applications appearing on any advertising, and we will not be a party to or in any way be responsible for monitoring any transaction between you and any third-party providers of products or services. As with the purchase or use of a product or service through any medium or in any environment, you should use your best judgment and exercise caution where appropriate. FOR AVOIDANCE OF DOUBT, THE REPORT, ITS CONTENT, ACCESS, AND/OR USAGE THEREOF, INCLUDING ANY ASSOCIATED SERVICES OR MATERIALS, SHALL NOT BE CONSIDERED OR RELIED UPON AS ANY FORM OF FINANCIAL, INVESTMENT, TAX, LEGAL, REGULATORY, OR OTHER ADVICE. Ondo Finance 3Audit
---
# Unknown
// Security Assessment11.27.2024 - 12.31.2024 Sources, Recipients and Instant Redemptions Ondo Finance Sources, Recipients and Instant Redemptions - Ondo Finance Prepared by:HALBORN Last Updated 02/14/2025 Date of Engagement by: November 27th, 2024 - December 31st, 2024 Summary OF ALL REPORTED FINDINGS HAVE BEEN ADDRESSED ALL FINDINGS 5 CRITICAL 0 HIGH 0 MEDIUM 1 LOW 1 INFORMATIONAL 3 TABLE OF CONTENTS 1. Introduction 2. Assessment summary 3. Test approach and methodology 4. Risk methodology 5. Scope 6. Assessment summary & findings overview 7. Findings & Tech Details 7.1 System does not support all major stable coins as intended 7.2 Deprecated openzeppelin functions 7.3 Unused custom errors 7.4 Centralization risk for trusted entities and roles 7.5 Event fields are missing \`indexed\` attribute 8. Automated Testing 100% 1. Introduction Ondo Finance engaged Halborn to conduct a security assessment on their smart contracts beginning on November 27th, 2024 and ending on January 1st, 2025. The security assessment was scoped to the smart contracts provided in the private repository provided to Halborn. Further details can be found in the Scope section of this report. 2. Assessment Summary Halborn was provided four weeks for the engagement, and assigned one full-time security engineer to review the security of the smart contracts in scope. The engineer is a blockchain and smart contract security expert with advanced penetration testing and smart contract hacking skills, and deep knowledge of multiple blockchain protocols. The purpose of the assessment is to: Identify potential security issues within the smart contracts. Ensure that smart contract functionality operates as intended. In summary, Halborn identified some improvements to reduce the likelihood and impact of risks, which were mostly addressed by the Ondo Finance team. The main ones were the following: Use SafeERC20 across all ERC20 operations, including "transfer", "transferFrom" and "forceApprove", for enhanced flexibility and secure compatibility with a myriad of ERC20 tokens. Update the OpenZeppelin dependencies to the latest version (v.5.x). Replace instances of \_setupRole() with \_grantRole() or equivalent role-management patterns. Add the indexed keyword when declaring events for better off-chain fetching. Implement multi-signature wallets with a sound threshold (e.g., a simple majority) for key administrative functions can provide an additional layer of security. Remove unused custom errors and ensure that any relevant error checks consistently reference active custom errors. 3. Test Approach And Methodology Halborn performed a combination of manual and automated security testing to balance efficiency, timeliness, practicality, and accuracy in regard to the scope of this assessment. While manual testing is recommended to uncover flaws in logic, process, and implementation; automated testing techniques help enhance coverage of the code and can quickly identify items that do not follow the security best practices. The following phases and associated tools were used during the assessment: Research into architecture and purpose. Smart contract manual code review and walkthrough. Graphing out functionality and contract logic/connectivity/functions (solgraph). Manual assessment of use and safety for the critical Solidity variables and functions in scope to identify any arithmetic related vulnerability classes. Manual testing by custom scripts. Static Analysis of security for scoped contract, and imported functions (slither). Testnet deployment (Foundry). 4. RISK METHODOLOGY Every vulnerability and issue observed by Halborn is ranked based on two sets of Metrics and a Severity Coefficient. This system is inspired by the industry standard Common Vulnerability Scoring System. The two Metric sets are: Exploitability and Impact. Exploitability captures the ease and technical means by which vulnerabilities can be exploited and Impact describes the consequences of a successful exploit. The Severity Coefficients is designed to further refine the accuracy of the ranking with two factors: Reversibility and Scope. These capture the impact of the vulnerability on the environment as well as the number of users and smart contracts affected. The final score is a value between 0-10 rounded up to 1 decimal place and 10 corresponding to the highest security risk. This provides an objective and accurate rating of the severity of security vulnerabilities in smart contracts. The system is designed to assist in identifying and prioritizing vulnerabilities based on their level of risk to address the most critical issues in a timely manner. 4.1 EXPLOITABILITY ATTACK ORIGIN (AO): Captures whether the attack requires compromising a specific account. ATTACK COST (AC): Captures the cost of exploiting the vulnerability incurred by the attacker relative to sending a single transaction on the relevant blockchain. Includes but is not limited to financial and computational cost. ATTACK COMPLEXITY (AX): Describes the conditions beyond the attacker’s control that must exist in order to exploit the vulnerability. Includes but is not limited to macro situation, available third-party liquidity and regulatory challenges. METRICS: EXPLOITABILITY METRIC () METRIC VALUENUMERICAL VALUE Attack Origin (AO) Arbitrary (AO:A) Specific (AO:S) 1 0.2 Attack Cost (AC) Low (AC:L) Medium (AC:M) High (AC:H) 1 0.67 0.33 Attack Complexity (AX) Low (AX:L) Medium (AX:M) High (AX:H) 1 0.67 0.33 Exploitability is calculated using the following formula: 4.2 IMPACT CONFIDENTIALITY (C): Measures the impact to the confidentiality of the information resources managed by the contract due to a successfully exploited vulnerability. Confidentiality refers to limiting access to authorized users only. INTEGRITY (I): Measures the impact to integrity of a successfully exploited vulnerability. Integrity refers to the trustworthiness and veracity of data stored and/or processed on-chain. Integrity impact directly affecting Deposit or Yield records is excluded. AVAILABILITY (A): Measures the impact to the availability of the impacted component resulting from a successfully exploited vulnerability. This metric refers to smart contract features and functionality, not state. Availability impact directly affecting Deposit or Yield is excluded. DEPOSIT (D): Measures the impact to the deposits made to the contract by either users or owners. YIELD (Y): M E E E=m ∏ e Measures the impact to the yield generated by the contract for either users or owners. METRICS: IMPACT METRIC () METRIC VALUENUMERICAL VALUE Confidentiality (C) None (I:N) Low (I:L) Medium (I:M) High (I:H) Critical (I:C) 0 0.25 0.5 0.75 1 Integrity (I) None (I:N) Low (I:L) Medium (I:M) High (I:H) Critical (I:C) 0 0.25 0.5 0.75 1 Availability (A) None (A:N) Low (A:L) Medium (A:M) High (A:H) Critical (A:C) 0 0.25 0.5 0.75 1 Deposit (D) None (D:N) Low (D:L) Medium (D:M) High (D:H) Critical (D:C) 0 0.25 0.5 0.75 1 Yield (Y) None (Y:N) Low (Y:L) Medium (Y:M) High (Y:H) Critical (Y:C) 0 0.25 0.5 0.75 1 Impact is calculated using the following formula: 4.3 SEVERITY COEFFICIENT REVERSIBILITY (R): Describes the share of the exploited vulnerability effects that can be reversed. For upgradeable contracts, assume the contract private key is available. SCOPE (S): Captures whether a vulnerability in one vulnerable contract impacts resources in other contracts. METRICS: M I I I=max(m )+ I 4 m −max(m )∑ II SEVERITY COEFFICIENT () COEFFICIENT VALUENUMERICAL VALUE Reversibility () None (R:N) Partial (R:P) Full (R:F) 1 0.5 0.25 Scope () Changed (S:C) Unchanged (S:U) 1.25 1 Severity Coefficient is obtained by the following product: The Vulnerability Severity Score is obtained by: The score is rounded up to 1 decimal places. SEVERITYSCORE VALUE RANGE Critical9 - 10 High7 - 8.9 Medium4.5 - 6.9 Low2 - 4.4 C r s C C=rs S S=min(10,EIC∗10) SEVERITYSCORE VALUE RANGE Informational0 - 1.9 5. SCOPE Out-of-Scope: New features/implementations after the remediation commit IDs. 6. ASSESSMENT SUMMARY & FINDINGS OVERVIEW CRITICAL 0 HIGH 0 MEDIUM 1 LOW 1 INFORMATIONAL 3 SECURITY ANALYSISRISK LEVELREMEDIATION DATE HAL-01 - SYSTEM DOES NOT SUPPORT ALL MAJOR STABLE COINS AS INTENDED MEDIUMSOLVED - 01/22/2025 HAL-01 - DEPRECATED OPENZEPPELIN FUNCTIONS LOWSOLVED - 01/22/2025 HAL-05 - UNUSED CUSTOM ERRORSINFORMATIONALSOLVED - 01/22/2025 HAL-03 - CENTRALIZATION RISK FOR TRUSTED ENTITIES AND ROLES INFORMATIONAL ACKNOWLEDGED - 01/22/2025 HAL-02 - EVENT FIELDS ARE MISSING \`INDEXED\` ATTRIBUTE INFORMATIONALSOLVED - 01/22/2025 7. FINDINGS & TECH DETAILS 7.1 (HAL-01) SYSTEM DOES NOT SUPPORT ALL MAJOR STABLE COINS AS INTENDED // MEDIUM Description Considering that the OUSG\_InstantManager and BaseRWAManager contracts should be as flexible as possible in terms of allowed depositTokens, configurable through access-controlled methods, the vulnerability arises because OUSG\_InstantManager inherits from BaseRWAManager and calls functions like \_processSubscription (in BaseRWAManager.sol) without checking the return value of ERC20 transferFrom calls. Specifically, in OUSG\_InstantManager.sol (for instance, in subscribe and subscribeRebasingOUSG), the code invokes \_processSubscription with a user-supplied token but never validates the Boolean result of transferFrom. - contracts/xManager/rwaManagers/BaseRWAManager.sol /\*\* /\*\* \* @notice Internal function for processing subscriptions \* @notice Internal function for processing subscriptions \* @param depositToken The token to deposit \* @param depositToken The token to deposit \* @param depositAmount The amount of tokens to deposit, in \* @param depositAmount The amount of tokens to deposit, in \* token being deposited \* token being deposited \* @param minimumRwaReceived The minimum amount of RWA tokens to \* @param minimumRwaReceived The minimum amount of RWA tokens to \* decimals of the RWA token \* decimals of the RWA token \* @return rwaAmountOut The amount of RWA tokens to mint or \* @return rwaAmountOut The amount of RWA tokens to mint or \* decimals of the RWA token \* decimals of the RWA token \* @dev This function will transfer the deposit tokens from the \* @dev This function will transfer the deposit tokens from the \* and then deposit them via the \`OndoTokenRouter\`. The mi \* and then deposit them via the \`OndoTokenRouter\`. The mi \* must be done in the child class. \* must be done in the child class. \*/ \*/ function function \_processSubscription \_processSubscription ( ( address address depositToken depositToken , , uint256 uint256 depositAmount depositAmount , , uint256 uint256 minimumRwaReceived minimumRwaReceived ) ) internal internal whenSubscribeNotPaused whenSubscribeNotPaused returns returns ( ( uint256 uint256 rwaAmountOut rwaAmountOut ) ) { { if if ( ( ! ! acceptedSubscriptionTokens acceptedSubscriptionTokens \[ \[ depositToken depositToken \] \] ) ) revert revert TokenNotAc TokenNotAc if if ( ( IERC20 IERC20 ( ( depositToken depositToken ) ) . . allowance allowance ( ( \_msgSender \_msgSender ( ( ) ) , , address address ( ( this this ) ) ) ) < < depositAmount depositAmount 149 149 150 150 151 151 152 152 153 153 154 154 155 155 156 156 157 157 158 158 159 159 160 160 161 161 162 162 163 163 164 164 165 165 166 166 167 167 168 168 169 169 170 170 ) ) revert revert InsufficientAllowance InsufficientAllowance ( ( ) ) ; ; // Reverts if user address is not compliant // Reverts if user address is not compliant ondoCompliance ondoCompliance . . checkIsCompliant checkIsCompliant ( ( rwaToken rwaToken , , \_msgSender \_msgSender ( ( ) ) ) ) ; ; bytes32 bytes32 userId userId = = ondoIDRegistry ondoIDRegistry . . getRegisteredID getRegisteredID ( ( rwaToken rwaToken , , \_msgSe \_msgSe if if ( ( userId userId == == bytes32 bytes32 ( ( 0 0 ) ) ) ) revert revert UserNotRegistered UserNotRegistered ( ( ) ) ; ; IERC20 IERC20 ( ( depositToken depositToken ) ) . . transferFrom transferFrom ( ( \_msgSender \_msgSender ( ( ) ) , , address address ( ( this this ) ) , , depositAmount depositAmount ) ) ; ; IERC20 IERC20 ( ( depositToken depositToken ) ) . . approve approve ( ( address address ( ( ondoTokenRouter ondoTokenRouter ) ) , , depositAm depositAm ondoTokenRouter ondoTokenRouter . . depositToken depositToken ( ( rwaToken rwaToken , , depositToken depositToken , , depositAmou depositAmou // USD values are normalized to 18 decimals // USD values are normalized to 18 decimals uint256 uint256 depositUSDValue depositUSDValue = = ( ( ondoOracle ondoOracle . . getAssetPrice getAssetPrice ( ( depositToken depositToken depositAmount depositAmount ) ) / / 10 10 \*\* \*\* IERC20Metadata IERC20Metadata ( ( depositToken depositToken ) ) . . decimals decimals ( ( ) ) if if ( ( depositUSDValue depositUSDValue < < minimumDepositUSD minimumDepositUSD ) ) revert revert DepositAmountToo DepositAmountToo // Fee in USD with 18 decimals // Fee in USD with 18 decimals uint256 uint256 fee fee = = ondoSubscriptionFees ondoSubscriptionFees . . getAndUpdateFee getAndUpdateFee ( ( rwaToken rwaToken , , depositToken depositToken , , userId userId , , depositUSDValue depositUSDValue ) ) ; ; if if ( ( fee fee > > depositUSDValue depositUSDValue ) ) revert revert FeeGreaterThanSubscription FeeGreaterThanSubscription ( ( ) ) ; ; // Prices are returned in 18 decimals. // Prices are returned in 18 decimals. rwaAmountOut rwaAmountOut = = ( ( ( ( ( ( ( ( depositUSDValue depositUSDValue - - fee fee ) ) \* \* USD\_NORMALIZER USD\_NORMALIZER ) ) / / \_getRwaPrice \_getRwaPrice ( ( ) ) ) ) RWA\_NORMALIZER RWA\_NORMALIZER ) ) / / USD\_NORMALIZER USD\_NORMALIZER ; ; if if ( ( rwaAmountOut rwaAmountOut < < minimumRwaReceived minimumRwaReceived ) ) revert revert RwaReceiveAmountTo RwaReceiveAmountTo ondoRateLimiter ondoRateLimiter . . checkAndUpdateRateLimit checkAndUpdateRateLimit ( ( IOndoRateLimiter IOndoRateLimiter . . TransactionType TransactionType . . SUBSCRIPTION SUBSCRIPTION , , rwaToken rwaToken , , userId userId , , 171 171 172 172 173 173 174 174 175 175 176 176 177 177 178 178 179 179 180 180 181 181 182 182 183 183 184 184 185 185 186 186 187 187 188 188 189 189 190 190 191 191 192 192 193 193 194 194 195 195 196 196 197 197 198 198 199 199 200 200 201 201 202 202 203 203 204 204 205 205 206 206 207 207 208 208 209 209 210 210 211 211 212 212 213 213 214 214 This is problematic when dealing with tokens such as ZRX that silently return false, because the contract proceeds as though tokens were successfully transferred when no actual transfer occurred. Additionally, in the same functions, tokens like USDT that revert on non-Boolean transfer logic can cause an unexpected revert, leading to a complete denial-of-service (DoS) for users trying to deposit that token. In the case of tokens such as 0x ($ZRX), which always returns false, the code around \_processSubscription in BaseRWAManager.sol logs the deposit, approves and calls the router, then mints OUSG to the depositor, even though the actual ERC20 transfer never took place. Attackers can repeatedly call subscribe with ZRX, accumulate OUSG without ever expending real assets, and then redeem that newly minted OUSG for legitimate tokens if redemption is supported. Meanwhile, tokens like USDT that do not return a standard Boolean on transferFrom can cause the contract logic in OUSG\_InstantManager to revert unexpectedly if the code tries to assign the result to a bool variable or otherwise interpret the missing return value. This leads to a DoS for USDT-based deposits because the contract is unprepared to handle non-Boolean behaviors, causing all subsequent deposit attempts to fail. The net result is two significant outcomes that undermine the system’s reliability. First, a malicious user can mint unlimited OUSG by exploiting the unsafe transfer logic with a token that returns false (or otherwise fails silently), such as 0x ($ZRX). Second, well-intentioned USDT holders cannot deposit their tokens, as the missing Boolean return from USDT triggers unexpected revert paths that effectively lock them out of subscription functionality. These conditions compromise both the monetary security and usability of the contract, leading to Denial of Service. Proof of Concept depositUSDValue depositUSDValue ) ) ; ; emit emit Subscription Subscription ( ( \_msgSender \_msgSender ( ( ) ) , , userId userId , , rwaAmountOut rwaAmountOut , , depositToken depositToken , , depositAmount depositAmount , , depositUSDValue depositUSDValue , , fee fee ) ) ; ; } } 215 215 216 216 217 217 218 218 219 219 220 220 221 221 222 222 223 223 224 224 225 225 226 226 227 227 To reproduce this vulnerability, consider running the following Foundry tests, one for each case. Case 1 - Unsafe transfer (ZRX) leads to infinite OUSG minting PoC Code: // Case 1 // Case 1 function function test\_halborn\_ExploitWithZRXMock test\_halborn\_ExploitWithZRXMock ( ( ) ) public public { { vm vm . . startPrank startPrank ( ( attacker attacker ) ) ; ; zrxMock zrxMock . . approve approve ( ( address address ( ( manager manager ) ) , , 1 1 \_000 ether \_000 ether ) ) ; ; // Use the OUSG\_InstantManager's subscribe method with non-standard t // Use the OUSG\_InstantManager's subscribe method with non-standard t // The manager calls \`transferFrom(attacker, manager, 300k)\`, which r // The manager calls \`transferFrom(attacker, manager, 300k)\`, which r // but the manager incorrectly assumes success and mints OUSG to atta // but the manager incorrectly assumes success and mints OUSG to atta manager manager . . subscribe subscribe ( ( address address ( ( zrxMock zrxMock ) ) , , 1 1 \_000 ether \_000 ether , , 900 900 \_000000 \_000000 ) ) ; ; vm vm . . stopPrank stopPrank ( ( ) ) ; ; uint256 uint256 attackerOusg attackerOusg = = mockOUSG mockOUSG . . balanceOf balanceOf ( ( attacker attacker ) ) ; ; emit emit log\_named\_uint log\_named\_uint ( ( "Attacker minted OUSG out of thin air" "Attacker minted OUSG out of thin air" , , attackerO attackerO // This proves the contract minted OUSG while no real tokens were tra // This proves the contract minted OUSG while no real tokens were tra require require ( ( attackerOusg attackerOusg > > 0 0 , , "Exploit failed: attacker not credited with "Exploit failed: attacker not credited with } } Logs: Case 2 - Unsafe transferFrom (USDT) leads to DoS PoC Code: // Case 2 // Case 2 function function test\_halborn\_USDTDeposit test\_halborn\_USDTDeposit ( ( ) ) public public { { // Impersonate a real USDT whale // Impersonate a real USDT whale vm vm . . startPrank startPrank ( ( usdtWhale usdtWhale ) ) ; ; // Approve manager for some USDT // Approve manager for some USDT IERC20 IERC20 ( ( USDT\_MAINNET USDT\_MAINNET ) ) . . safeApprove safeApprove ( ( address address ( ( manager manager ) ) , , 1000 1000 \_000000 \_000000 ) ) ; ; // e // e // Now try to deposit // Now try to deposit vm vm . . expectRevert expectRevert ( ( ) ) ; ; manager manager . . subscribe subscribe ( ( USDT\_MAINNET USDT\_MAINNET , , 1000 1000 \_000000 \_000000 , , 1 1 ether ether ) ) ; ; // If the manager code doesn't properly handle the USDT transfer (whi // If the manager code doesn't properly handle the USDT transfer (whi // we could see a revert or unexpected behavior. // we could see a revert or unexpected behavior. vm vm . . stopPrank stopPrank ( ( ) ) ; ; } } Logs: BVSS AO:A/AC:L/AX:L/R:N/S:U/C:N/A:M/I:N/D:N/Y:N (5.0) Recommendation A direct remediation is to adopt SafeERC20 practices or otherwise require a successful transfer outcome before proceeding with the logic that mints OUSG. By checking the return status of each transferFrom call, the contract ensures that funds truly change hands when a deposit is made, and it can gracefully handle tokens like USDT that revert on non-compliant calls by implementing specialized wrappers or logic that does not rely on receiving a simple bool. Remediation Comment SOLVED: The Ondo Finance team has solved this issue as recommended, by implementing SafeERC20 methods. References \[\] 7.2 (HAL-01) DEPRECATED OPENZEPPELIN FUNCTIONS // LOW Description The \_setupRole() function from OpenZeppelin's Access Control library is used extensively across the provided contracts to assign roles, including DEFAULT\_ADMIN\_ROLE. However, this function has been deprecated in favor of updated role-management practices, such as directly assigning roles in constructors or using \_grantRole() for manual role setup. While \_setupRole() remains functional, its use is discouraged as it may not align with future updates to the OpenZeppelin library, potentially leading to maintainability and compatibility issues. - contracts/xManager/OndoCompliance.sol - contracts/xManager/OndoFees.sol - contracts/xManager/OndoIDRegistry/OndoIDRegistry.sol - contracts/xManager/OndoIDRegistry/OndoIDRegistryView.sol - contracts/xManager/OndoRateLimiter.sol - contracts/xManager/rwaManagers/BaseRWAManager.sol \_setupRole \_setupRole ( ( DEFAULT\_ADMIN\_ROLE DEFAULT\_ADMIN\_ROLE , , admin admin ) ) ; ; 97 97 \_setupRole \_setupRole ( ( DEFAULT\_ADMIN\_ROLE DEFAULT\_ADMIN\_ROLE , , guardian guardian ) ) ; ; 209 209 \_setupRole \_setupRole ( ( DEFAULT\_ADMIN\_ROLE DEFAULT\_ADMIN\_ROLE , , admin admin ) ) ; ; 102 102 \_setupRole \_setupRole ( ( DEFAULT\_ADMIN\_ROLE DEFAULT\_ADMIN\_ROLE , , msg msg . . sender sender ) ) ; ; 65 65 \_setupRole \_setupRole ( ( DEFAULT\_ADMIN\_ROLE DEFAULT\_ADMIN\_ROLE , , guardian guardian ) ) ; ; 152 152 \_setupRole \_setupRole ( ( DEFAULT\_ADMIN\_ROLE DEFAULT\_ADMIN\_ROLE , , \_defaultAdmin \_defaultAdmin ) ) ; ; 146 146 - contracts/xManager/tokenManagers/PauseManager.sol - contracts/xManager/tokenManagers/tokenRecipients/UsdsPSMRecipient.sol - contracts/xManager/tokenManagers/tokenSources/BuidlUSDCSource.sol - contracts/xManager/tokenManagers/tokenSources/PSMSource.sol - contracts/xManager/tokenRouter/OndoTokenRouter.sol BVSS AO:A/AC:L/AX:L/C:N/I:L/A:N/D:N/Y:N/R:N/S:C (3.1) Recommendation Replace instances of \_setupRole() with \_grantRole() or equivalent role-management patterns. For role assignments during contract initialization, roles should be configured directly within constructors where applicable. This approach ensures alignment with OpenZeppelin's recommended practices and improves future-proofing of the codebase. For example: \_setupRole \_setupRole ( ( DEFAULT\_ADMIN\_ROLE DEFAULT\_ADMIN\_ROLE , , \_defaultAdmin \_defaultAdmin ) ) ; ; 146 146 \_setupRole \_setupRole ( ( PAUSE\_CONTRACT\_ROLE PAUSE\_CONTRACT\_ROLE , , \_defaultAdmin \_defaultAdmin ) ) ; ; 93 93 \_setupRole \_setupRole ( ( UNPAUSE\_CONTRACT\_ROLE UNPAUSE\_CONTRACT\_ROLE , , \_defaultAdmin \_defaultAdmin ) ) ; ; 94 94 \_setupRole \_setupRole ( ( DEFAULT\_ADMIN\_ROLE DEFAULT\_ADMIN\_ROLE , , \_defaultAdmin \_defaultAdmin ) ) ; ; 82 82 \_setupRole \_setupRole ( ( DEFAULT\_ADMIN\_ROLE DEFAULT\_ADMIN\_ROLE , , \_defaultAdmin \_defaultAdmin ) ) ; ; 125 125 \_setupRole \_setupRole ( ( DEFAULT\_ADMIN\_ROLE DEFAULT\_ADMIN\_ROLE , , \_defaultAdmin \_defaultAdmin ) ) ; ; 81 81 \_setupRole \_setupRole ( ( DEFAULT\_ADMIN\_ROLE DEFAULT\_ADMIN\_ROLE , , \_defaultAdmin \_defaultAdmin ) ) ; ; 82 82 \_grantRole \_grantRole ( ( DEFAULT\_ADMIN\_ROLE DEFAULT\_ADMIN\_ROLE , , \_defaultAdmin \_defaultAdmin ) ) ; ; Remediation Comment SOLVED: The Ondo Finance team has solved this issue as recommended. References \[\] 7.3 (HAL-05) UNUSED CUSTOM ERRORS // INFORMATIONAL Description Custom errors are a Solidity feature that helps save gas and provide clear feedback when a require statement fails. However, declaring a custom error that is never actually used in the contract confuses readers and suggests incomplete or abandoned functionality. Leaving unused errors in place may mislead auditors to think that certain scenarios require custom handling or that they were important in a previously removed feature. The extra code can also distract from active logic and hamper the overall maintainability of the contract by introducing superfluous elements. - contracts/xManager/tokenManagers/tokenRecipients/UsdsPSMRecipient.sol - contracts/xManager/tokenManagers/tokenSources/PSMSource.sol Proof of Concept BVSS AO:A/AC:L/AX:L/R:F/S:C/C:N/A:N/I:L/D:N/Y:N (0.8) Recommendation Remove unused custom errors and ensure that any relevant error checks consistently reference active custom errors. This maintains a clean codebase, reduces confusion, and makes the contract’s logic clearer for future readers and maintainers. Remediation Comment SOLVED: The Ondo Finance team has solved this issue as recommended. error error UnexpectedTokenMetadata UnexpectedTokenMetadata ( ( address address tokenSource tokenSource , , address address tokenAddr tokenAddr 62 62 error error UnexpectedTokenMetadata UnexpectedTokenMetadata ( ( address address tokenSource tokenSource , , address address tokenAddr tokenAddr 60 60 7.4 (HAL-03) CENTRALIZATION RISK FOR TRUSTED ENTITIES AND ROLES // INFORMATIONAL Description The system relies on role-based access control (onlyRole modifiers) to manage critical operations, concentrating significant authority in trusted roles. While this design allows for operational efficiency and security under controlled conditions, it introduces a centralization risk. The dependency on a limited number of privileged actors could potentially undermine the trustless and decentralized characteristics expected of blockchain protocols. Misuse or compromise of these roles may lead to operational or financial risks. The issue is primarily informational in nature, as such centralized designs are often intentional for operational simplicity or compliance. However, it is important to highlight this risk to ensure stakeholders remain aware of its implications. BaseRWAManager.sol - contracts/xManager/rwaManagers/BaseRWAManager.sol Line: 56, 318, 363, 379, 393, 407, 422, 438, 452, 464, 482, 497, 513, 525, 539, 554, 563, 569, 575, 581 OUSG\_InstantManager.sol - contracts/xManager/rwaManagers/OUSG\_InstantManager.sol \[multiple lines with onlyRole(...) – for example Line: 53, 523\] OndoIDRegistry.sol - contracts/xManager/OndoIDRegistry/OndoIDRegistry.sol Line: 186 OndoIDRegistryView.sol - contracts/xManager/OndoIDRegistry/OndoIDRegistryView.sol Line: 30, 120, 135 OndoCompliance.sol - contracts/xManager/OndoCompliance.sol Line: 32, 165 OndoFees.sol - contracts/xManager/OndoFees.sol Line: 42, 225, 429, 458, 480, 505, 544 OndoOracle.sol - contracts/xManager/OndoOracle/OndoOracle.sol Line: 41, 220, 247, 271, 315 OndoRateLimiter.sol - contracts/xManager/OndoRateLimiter.sol Line: 29, 167, 371, 399, 427, 453, 481, 513 AbstractRWAOracleWrapper.sol - contracts/xManager/OndoOracle/AbstractRWAOracleWrapper.sol Line: 28, 72 OndoTokenRouter.sol - contracts/xManager/tokenRouter/OndoTokenRouter.sol Line: 31, 96, 132, 259, 287, 314, 334, 398 BasicRecipient.sol - contracts/xManager/tokenManagers/tokenRecipients/BasicRecipient.sol Line: 61 UsdsPSMRecipient.sol - contracts/xManager/tokenManagers/tokenRecipients/UsdsPSMRecipient.sol Line: 107 BasicSource.sol - contracts/xManager/tokenManagers/tokenSources/BasicSource.sol Line: 72 BuidlUSDCSource.sol - contracts/xManager/tokenManagers/tokenSources/BuidlUSDCSource.sol Line: 148, 264 PSMSource.sol - contracts/xManager/tokenManagers/tokenSources/PSMSource.sol Line: 106 SudsSource (SusdsSource.sol) - contracts/xManager/tokenManagers/tokenSources/SusdsSource.sol Line: 75 PauseManager.sol - contracts/xManager/tokenManagers/PauseManager.sol Line: 28, 104, 117, 126, 138, 148, 158 Proof of Concept BVSS AO:S/AC:L/AX:L/R:N/S:C/C:N/A:N/I:M/D:N/Y:N (1.3) Recommendation It is suggested to implement multi-signature wallets with a sound threshold (e.g., a simple majority) for key administrative functions can provide an additional layer of security. This approach distributes authority among multiple trusted entities, reducing the risk of unilateral actions while maintaining operational efficiency. Furthermore, transparent documentation and periodic reviews of role assignments can strengthen overall governance without significantly complicating the system. Remediation Comment ACKNOWLEDGED: The Ondo Finance team has acknowledged this issue. 7.5 (HAL-02) EVENT FIELDS ARE MISSING \`INDEXED\` ATTRIBUTE // INFORMATIONAL Description Indexed event fields make the data more quickly accessible to off-chain tools that parse events, and add them to a special data structure known as “topics” instead of the data part of the log. A topic can only hold a single word (32 bytes) so if you use a reference type for an indexed argument, the Keccak-256 hash of the value is stored as a topic instead. Each event can use up to three indexed fields. If there are fewer than three fields, all the fields can be indexed. It is important to note that each index field costs extra gas during emission, so it's not necessarily best to index the maximum allowed fields per event (three indexed fields). This is specially recommended when gas usage is not particularly of concern for the emission of the events in question, and the benefits of querying those fields in an easier and straight-forward manner surpasses the downsides of gas usage increase. - contracts/xManager/rwaManagers/IBaseRWAManagerEvents.sol - contracts/xManager/rwaManagers/IBaseRWAManagerEvents.sol - contracts/xManager/rwaManagers/IBaseRWAManagerEvents.sol - contracts/xManager/rwaManagers/IBaseRWAManagerEvents.sol - contracts/xManager/rwaManagers/IBaseRWAManagerEvents.sol event event Subscription Subscription ( ( 30 30 event event Redemption Redemption ( ( 52 52 event event AcceptedSubscriptionTokenSet AcceptedSubscriptionTokenSet ( ( address address indexed indexed token token , , bool bool 164 164 event event AcceptedRedemptionTokenSet AcceptedRedemptionTokenSet ( ( address address indexed indexed token token , , bool bool 171 171 event event MinimumDepositAmountSet MinimumDepositAmountSet ( ( 178 178 - contracts/xManager/rwaManagers/IBaseRWAManagerEvents.sol - contracts/xManager/rwaManagers/IBaseRWAManagerEvents.sol - contracts/xManager/rwaManagers/OUSG\_InstantManager.sol - contracts/xManager/rwaManagers/OUSG\_InstantManager.sol - contracts/xManager/rwaManagers/OUSG\_InstantManager.sol - contracts/xManager/rwaManagers/AdminSubscriptionChecker.sol BVSS AO:A/AC:L/AX:L/R:F/S:C/C:N/A:N/I:L/D:N/Y:N (0.8) Recommendation It is recommended to add the indexed keyword when declaring events, considering the following example: event event Indexed Indexed ( ( address address indexed indexed from from , , bytes32 bytes32 indexed indexed id id , , event event MinimumRedemptionAmountSet MinimumRedemptionAmountSet ( ( 188 188 event event MinimumRwaPriceSet MinimumRwaPriceSet ( ( 198 198 event event InstantSubscriptionRebasingOUSG InstantSubscriptionRebasingOUSG ( ( 48 48 event event InstantRedemptionRebasingOUSG InstantRedemptionRebasingOUSG ( ( 64 64 event event AdminSubscriptionRebasingOUSG AdminSubscriptionRebasingOUSG ( ( 79 79 event event AdminSubscriptionAllowanceSet AdminSubscriptionAllowanceSet ( ( address address indexed indexed admin admin , , uin uin 47 47 uint uint indexed indexed value value ) ) ; ; Remediation Comment SOLVED: The Ondo Finance team has solved this issue as recommended. 8. AUTOMATED TESTING Halborn used automated testing techniques to enhance the coverage of certain areas of the smart contracts in scope. Among the tools used was Slither, a Solidity static analysis framework. After Halborn verified the smart contracts in the repository and was able to compile them correctly into their ABIs and binary format, Slither was run against the contracts. This tool can statically verify mathematical relationships between Solidity variables to detect invalid or inconsistent usage of the contracts' APIs across the entire code-base. The security team conducted a comprehensive review of all findings generated by the Slither static analysis tool. After careful examination and consideration of the flagged issues, it was determined that within the project's specific context and scope, all were false positives or irrelevant. Halborn strongly recommends conducting a follow-up assessment of the project either within six months or immediately following any material changes to the codebase, whichever comes first. This approach is crucial for maintaining the project’s integrity and addressing potential vulnerabilities introduced by code modifications.
---
# Unknown
// Private Cosmos Security Assessment07.01.2024 - 07.05.2024 Ondo - Tokenized Treasury Bill - Additional Aura Module Noble Ondo - Tokenized Treasury Bill - Additional Aura Module - Noble Prepared by:HALBORN Last Updated 07/16/2024 Date of Engagement by: July 1st, 2024 - July 5th, 2024 Summary OF ALL REPORTED FINDINGS HAVE BEEN ADDRESSED ALL FINDINGS 1 CRITICAL 0 HIGH 0 MEDIUM 0 LOW 0 INFORMATIONAL 1 TABLE OF CONTENTS 1. Introduction 2. Assessment summary 3. Test approach and methodology 4. Risk methodology 5. Scope 6. Assessment summary & findings overview 7. Findings & Tech Details 7.1 Implement multiple channel support for addblockedchannel 8. Automated Testing 100% 1. Introduction The Noble team engaged Halborn to conduct a security assessment on their forwarding module updates, beginning on Halborn to conduct a security assessment on the aura module updates, beginning on 07/01/2024 and ending on 07/04/2024. The security assessment was scoped to the sections of code that pertain to the aura module. Commit hashes and further details can be found in the Scope section of this report. 2. Assessment Summary Halborn was provided 4 days for the engagement and assigned 1 full-time security engineer to review the security of the smart contracts in scope. The engineer is a blockchain and smart contract security experts with advanced penetration testing and smart contract hacking skills, and deep knowledge of multiple blockchain protocols. The purpose of the assessment is to: - Ensure that the Noble Aura Module Updates operates as intended. - Identify potential security issues with the Noble Aura Module Updates in the Noble Chain. In summary, Halborn identified some security concerns that were accepted by the Noble team. 3. Test Approach And Methodology Halborn performed a combination of manual and automated security testing to balance eciency, timeliness, practicality, and accuracy in regard to the scope of the custom modules. While manual testing is recommended to uncover flaws in logic, process, and implementation; automated testing techniques help enhance coverage of structures and can quickly identify items that do not follow security best practices. The following phases and associated tools were used throughout the term of the assessment: - Research into architecture and purpose. - Static Analysis of security for scoped repository, and imported functions. (e.g., staticcheck, gosec, unconvert, codeql, ineffassign and semgrep) - Manual Assessment for discovering security vulnerabilities in the codebase. - Ensuring the correctness of the codebase. - Dynamic Analysis of files and modules related to the Aura Module. Out-Of-Scope External libraries and financial-related attacks. New features/implementations after/with the remediation/given commit IDs. 4. RISK METHODOLOGY Every vulnerability and issue observed by Halborn is ranked based on two sets of Metrics and a Severity Coecient. This system is inspired by the industry standard Common Vulnerability Scoring System. The two Metric sets are: Exploitability and Impact. Exploitability captures the ease and technical means by which vulnerabilities can be exploited and Impact describes the consequences of a successful exploit. The Severity Coecients is designed to further refine the accuracy of the ranking with two factors: Reversibility and Scope. These capture the impact of the vulnerability on the environment as well as the number of users and smart contracts affected. The final score is a value between 0-10 rounded up to 1 decimal place and 10 corresponding to the highest security risk. This provides an objective and accurate rating of the severity of security vulnerabilities in smart contracts. The system is designed to assist in identifying and prioritizing vulnerabilities based on their level of risk to address the most critical issues in a timely manner. 4.1 EXPLOITABILITY ATTACK ORIGIN (AO): Captures whether the attack requires compromising a specific account. ATTACK COST (AC): Captures the cost of exploiting the vulnerability incurred by the attacker relative to sending a single transaction on the relevant blockchain. Includes but is not limited to financial and computational cost. ATTACK COMPLEXITY (AX): Describes the conditions beyond the attacker’s control that must exist in order to exploit the vulnerability. Includes but is not limited to macro situation, available third-party liquidity and regulatory challenges. METRICS: EXPLOITABILIY METRIC () METRIC VALUENUMERICAL VALUE Attack Origin (AO) Arbitrary (AO:A) Specific (AO:S) 1 0.2 Attack Cost (AC) Low (AC:L) Medium (AC:M) High (AC:H) 1 0.67 0.33 M E EXPLOITABILIY METRIC () METRIC VALUENUMERICAL VALUE Attack Complexity (AX) Low (AX:L) Medium (AX:M) High (AX:H) 1 0.67 0.33 Exploitability is calculated using the following formula: 4.2 IMPACT CONFIDENTIALITY (C): Measures the impact to the confidentiality of the information resources managed by the contract due to a successfully exploited vulnerability. Confidentiality refers to limiting access to authorized users only. INTEGRITY (I): Measures the impact to integrity of a successfully exploited vulnerability. Integrity refers to the trustworthiness and veracity of data stored and/or processed on-chain. Integrity impact directly affecting Deposit or Yield records is excluded. AVAILABILITY (A): Measures the impact to the availability of the impacted component resulting from a successfully exploited vulnerability. This metric refers to smart contract features and functionality, not state. Availability impact directly affecting Deposit or Yield is excluded. DEPOSIT (D): Measures the impact to the deposits made to the contract by either users or owners. YIELD (Y): Measures the impact to the yield generated by the contract for either users or owners. METRICS: IMPACT METRIC () METRIC VALUENUMERICAL VALUE Confidentiality (C) None (I:N) Low (I:L) Medium (I:M) High (I:H) Critical (I:C) 0 0.25 0.5 0.75 1 M E E E=m ∏ e M I IMPACT METRIC () METRIC VALUENUMERICAL VALUE Integrity (I) None (I:N) Low (I:L) Medium (I:M) High (I:H) Critical (I:C) 0 0.25 0.5 0.75 1 Availability (A) None (A:N) Low (A:L) Medium (A:M) High (A:H) Critical (A:C) 0 0.25 0.5 0.75 1 Deposit (D) None (D:N) Low (D:L) Medium (D:M) High (D:H) Critical (D:C) 0 0.25 0.5 0.75 1 Yield (Y) None (Y:N) Low (Y:L) Medium (Y:M) High (Y:H) Critical (Y:C) 0 0.25 0.5 0.75 1 Impact is calculated using the following formula: 4.3 SEVERITY COEFFICIENT REVERSIBILITY (R): Describes the share of the exploited vulnerability effects that can be reversed. For upgradeable contracts, assume the contract private key is available. SCOPE (S): Captures whether a vulnerability in one vulnerable contract impacts resources in other contracts. METRICS: SEVERITY COEFFICIENT () COEFFICIENT VALUENUMERICAL VALUE Reversibility () None (R:N) Partial (R:P) Full (R:F) 1 0.5 0.25 Scope () Changed (S:C) Unchanged (S:U) 1.25 1 M I I I=max(m )+ I 4 m −max(m )∑ II C r s Severity Coecient is obtained by the following product: The Vulnerability Severity Score is obtained by: The score is rounded up to 1 decimal places. SEVERITYSCORE VALUE RANGE Critical9 - 10 High7 - 8.9 Medium4.5 - 6.9 Low2 - 4.4 Informational0 - 1.9 C C=rs S S=min(10,EIC∗10) 5. SCOPE FILES AND REPOSITORY (a) Repository: usdy-noble (b) Assessed Commit ID: 58ecd2a (c) Items in scope: x/aura Out-of-Scope: Out-of-Scope: New features/implementations after the remediation commit IDs. 6. ASSESSMENT SUMMARY & FINDINGS OVERVIEW CRITICAL 0 HIGH 0 MEDIUM 0 LOW 0 INFORMATIONAL 1 SECURITY ANALYSISRISK LEVELREMEDIATION DATE IMPLEMENT MULTIPLE CHANNEL SUPPORT FOR ADDBLOCKEDCHANNEL INFORMATIONALACKNOWLEDGED 7. FINDINGS & TECH DETAILS 7.1 IMPLEMENT MULTIPLE CHANNEL SUPPORT FOR ADDBLOCKEDCHANNEL // INFORMATIONAL Description Currently, the AddBlockedChannel function only supports blocking a single channel at a time. To improve eciency and user experience, we should modify this function to accept and process an array of channels. Proposed Changes: 1. Update the MsgAddBlockedChannel type to include an array of channels instead of a single channel. 2. Modify the AddBlockedChannel function to iterate through the array of channels. 3. Implement batch processing of channels, adding each to the blocked list. 4. Update error handling to provide feedback on which channels were successfully blocked and which encountered errors. 5. Modify the emitted event to include all successfully blocked channels. func (k msgServer) AddBlockedChannel(goCtx context.Context, msg \*types.MsgAddBlockedChannel) (\*types.MsgAddBlockedChannelResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) owner := k.GetOwner(ctx) if owner == "" { return nil, types.ErrNoOwner } if msg.Signer != owner { return nil, sdkerrors.Wrapf(types.ErrInvalidOwner, "expected %s, got %s", owner, msg.Signer) } if k.HasBlockedChannel(ctx, msg.Channel) { return nil, fmt.Errorf("%s is already blocked", msg.Channel) } k.SetBlockedChannel(ctx, msg.Channel) return &types.MsgAddBlockedChannelResponse{}, ctx.EventManager().EmitTypedEvent(&types.BlockedChannelAdded{ Channel: msg.Channel, }) } Score AO:A/AC:L/AX:L/C:N/I:N/A:N/D:N/Y:N/R:P/S:C (0.0) Recommendation Consider adding multi-channel messages on the keeper. Remediation Plan ACKNOWLEDGED: The Noble team acknowledged the issue. 8. AUTOMATED TESTING Halborn used automated testing techniques to enhance coverage of certain areas of the scoped component. Among the tools used were staticcheck, gosec, semgrep, unconvert, codeql and nancy. After Halborn verified all the code and scoped structures in the repository and was able to compile them correctly, these tools were leveraged on scoped structures. With these tools, Halborn can statically verify security related issues across the entire codebase. Staticcheck No result. Gosec No result. Errcheck No result. Halborn strongly recommends conducting a follow-up assessment of the project either within six months or immediately following any material changes to the codebase, whichever comes first. This approach is crucial for maintaining the project’s integrity and addressing potential vulnerabilities introduced by code modifications.
---
# Unknown
// Private Cosmos Security Assessment06.03.2024 - 06.21.2024 Ondo - Tokenized Treasury Bill Noble Ondo - Tokenized Treasury Bill - Noble Prepared by:HALBORN Last Updated 07/16/2024 Date of Engagement by: June 3rd, 2024 - June 21st, 2024 Summary OF ALL REPORTED FINDINGS HAVE BEEN ADDRESSED ALL FINDINGS 10 CRITICAL 0 HIGH 0 MEDIUM 3 LOW 0 INFORMATIONAL 7 TABLE OF CONTENTS 1. Introduction 2. Assessment summary 3. Test approach and methodology 4. Risk methodology 5. Scope 6. Assessment summary & findings overview 7. Findings & Tech Details 7.1 No validation check for new owner in transferownership 7.2 Lack of blacklist check when adding burners, pausers, and owners 7.3 Pause functionality does not affect mint and burn operations 7.4 Duplicate transactions in the mempool's data structures 7.5 Asa-2023-002: default blockparams.maxbytes configuration may increase block times and affect consensus participation in the noble app chain 7.6 Asa-2024-004: default evidence configuration parameters may limit window of validity for the noble app chain 7.7 Potential inconsistency in blocked address handling for usdy token transfers 7.8 Lack of simulation and fuzzing of the module invariant 7.9 Missing long descriptions in cli affects usability and user experience 7.10 Blocklist owner can add itself to the blocklist 100% 8. Automated Testing 1. Introduction The Noble team engaged Halborn to conduct a security assessment on their forwarding module updates, beginning on Halborn to conduct a security assessment on the forwarding module, beginning on 06/03/2024 and ending on 06/22/2024. The security assessment was scoped to the sections of code that pertain to the aura module. Commit hashes and further details can be found in the Scope section of this report. 2. Assessment Summary Halborn was provided 3 weeks for the engagement and assigned 1 full-time security engineer to review the security of the smart contracts in scope. The engineer is a blockchain and smart contract security experts with advanced penetration testing and smart contract hacking skills, and deep knowledge of multiple blockchain protocols. The purpose of the assessment is to: - Ensure that the Noble Aura Modules operates as intended. - Identify potential security issues with the Noble Aura Modules in the Noble Chain. In summary, Halborn identified some security concerns that were accepted and addressed by the Noble team. 3. Test Approach And Methodology Halborn performed a combination of manual and automated security testing to balance eciency, timeliness, practicality, and accuracy in regard to the scope of the custom modules. While manual testing is recommended to uncover flaws in logic, process, and implementation; automated testing techniques help enhance coverage of structures and can quickly identify items that do not follow security best practices. The following phases and associated tools were used throughout the term of the assessment: - Research into architecture and purpose. - Static Analysis of security for scoped repository, and imported functions. (e.g., staticcheck, gosec, unconvert, codeql, ineffassign and semgrep) - Manual Assessment for discovering security vulnerabilities in the codebase. - Ensuring the correctness of the codebase. - Dynamic Analysis of files and modules related to the Aura Module. Out-Of-Scope External libraries and financial-related attacks. New features/implementations after/with the remediation/given commit IDs. 4. RISK METHODOLOGY Every vulnerability and issue observed by Halborn is ranked based on two sets of Metrics and a Severity Coecient. This system is inspired by the industry standard Common Vulnerability Scoring System. The two Metric sets are: Exploitability and Impact. Exploitability captures the ease and technical means by which vulnerabilities can be exploited and Impact describes the consequences of a successful exploit. The Severity Coecients is designed to further refine the accuracy of the ranking with two factors: Reversibility and Scope. These capture the impact of the vulnerability on the environment as well as the number of users and smart contracts affected. The final score is a value between 0-10 rounded up to 1 decimal place and 10 corresponding to the highest security risk. This provides an objective and accurate rating of the severity of security vulnerabilities in smart contracts. The system is designed to assist in identifying and prioritizing vulnerabilities based on their level of risk to address the most critical issues in a timely manner. 4.1 EXPLOITABILITY ATTACK ORIGIN (AO): Captures whether the attack requires compromising a specific account. ATTACK COST (AC): Captures the cost of exploiting the vulnerability incurred by the attacker relative to sending a single transaction on the relevant blockchain. Includes but is not limited to financial and computational cost. ATTACK COMPLEXITY (AX): Describes the conditions beyond the attacker’s control that must exist in order to exploit the vulnerability. Includes but is not limited to macro situation, available third-party liquidity and regulatory challenges. METRICS: EXPLOITABILIY METRIC () METRIC VALUENUMERICAL VALUE Attack Origin (AO) Arbitrary (AO:A) Specific (AO:S) 1 0.2 Attack Cost (AC) Low (AC:L) Medium (AC:M) High (AC:H) 1 0.67 0.33 M E EXPLOITABILIY METRIC () METRIC VALUENUMERICAL VALUE Attack Complexity (AX) Low (AX:L) Medium (AX:M) High (AX:H) 1 0.67 0.33 Exploitability is calculated using the following formula: 4.2 IMPACT CONFIDENTIALITY (C): Measures the impact to the confidentiality of the information resources managed by the contract due to a successfully exploited vulnerability. Confidentiality refers to limiting access to authorized users only. INTEGRITY (I): Measures the impact to integrity of a successfully exploited vulnerability. Integrity refers to the trustworthiness and veracity of data stored and/or processed on-chain. Integrity impact directly affecting Deposit or Yield records is excluded. AVAILABILITY (A): Measures the impact to the availability of the impacted component resulting from a successfully exploited vulnerability. This metric refers to smart contract features and functionality, not state. Availability impact directly affecting Deposit or Yield is excluded. DEPOSIT (D): Measures the impact to the deposits made to the contract by either users or owners. YIELD (Y): Measures the impact to the yield generated by the contract for either users or owners. METRICS: IMPACT METRIC () METRIC VALUENUMERICAL VALUE Confidentiality (C) None (I:N) Low (I:L) Medium (I:M) High (I:H) Critical (I:C) 0 0.25 0.5 0.75 1 M E E E=m ∏ e M I IMPACT METRIC () METRIC VALUENUMERICAL VALUE Integrity (I) None (I:N) Low (I:L) Medium (I:M) High (I:H) Critical (I:C) 0 0.25 0.5 0.75 1 Availability (A) None (A:N) Low (A:L) Medium (A:M) High (A:H) Critical (A:C) 0 0.25 0.5 0.75 1 Deposit (D) None (D:N) Low (D:L) Medium (D:M) High (D:H) Critical (D:C) 0 0.25 0.5 0.75 1 Yield (Y) None (Y:N) Low (Y:L) Medium (Y:M) High (Y:H) Critical (Y:C) 0 0.25 0.5 0.75 1 Impact is calculated using the following formula: 4.3 SEVERITY COEFFICIENT REVERSIBILITY (R): Describes the share of the exploited vulnerability effects that can be reversed. For upgradeable contracts, assume the contract private key is available. SCOPE (S): Captures whether a vulnerability in one vulnerable contract impacts resources in other contracts. METRICS: SEVERITY COEFFICIENT () COEFFICIENT VALUENUMERICAL VALUE Reversibility () None (R:N) Partial (R:P) Full (R:F) 1 0.5 0.25 Scope () Changed (S:C) Unchanged (S:U) 1.25 1 M I I I=max(m )+ I 4 m −max(m )∑ II C r s Severity Coecient is obtained by the following product: The Vulnerability Severity Score is obtained by: The score is rounded up to 1 decimal places. SEVERITYSCORE VALUE RANGE Critical9 - 10 High7 - 8.9 Medium4.5 - 6.9 Low2 - 4.4 Informational0 - 1.9 C C=rs S S=min(10,EIC∗10) 5. SCOPE FILES AND REPOSITORY (a) Repository: aura (b) Assessed Commit ID: f51c30a (c) Items in scope: x/aura Out-of-Scope: FILES AND REPOSITORY (a) Repository: aura (b) Assessed Commit ID: f553945 (c) Items in scope: Out-of-Scope: REMEDIATION COMMIT ID: 44c811a44c811a Out-of-Scope: New features/implementations after the remediation commit IDs. 6. ASSESSMENT SUMMARY & FINDINGS OVERVIEW CRITICAL 0 HIGH 0 MEDIUM 3 LOW 0 INFORMATIONAL 7 SECURITY ANALYSISRISK LEVELREMEDIATION DATE NO VALIDATION CHECK FOR NEW OWNER IN TRANSFEROWNERSHIP MEDIUMSOLVED - 06/06/2024 LACK OF BLACKLIST CHECK WHEN ADDING BURNERS, PAUSERS, AND OWNERS MEDIUMRISK ACCEPTED PAUSE FUNCTIONALITY DOES NOT AFFECT MINT AND BURN OPERATIONS MEDIUMSOLVED - 06/16/2024 DUPLICATE TRANSACTIONS IN THE MEMPOOL'S DATA STRUCTURES INFORMATIONALACKNOWLEDGED ASA-2023-002: DEFAULT BLOCKPARAMS.MAXBYTES CONFIGURATION MAY INCREASE BLOCK TIMES AND AFFECT CONSENSUS PARTICIPATION IN THE NOBLE APP CHAIN INFORMATIONALACKNOWLEDGED ASA-2024-004: DEFAULT EVIDENCE CONFIGURATION PARAMETERS MAY LIMIT WINDOW OF VALIDITY FOR THE NOBLE APP CHAIN INFORMATIONALACKNOWLEDGED POTENTIAL INCONSISTENCY IN BLOCKED ADDRESS HANDLING FOR USDY TOKEN TRANSFERS INFORMATIONALACKNOWLEDGED LACK OF SIMULATION AND FUZZING OF THE MODULE INVARIANT INFORMATIONALACKNOWLEDGED MISSING LONG DESCRIPTIONS IN CLI AFFECTS USABILITY AND USER EXPERIENCE INFORMATIONALACKNOWLEDGED BLOCKLIST OWNER CAN ADD ITSELF TO THE BLOCKLIST INFORMATIONALACKNOWLEDGED 7. FINDINGS & TECH DETAILS 7.1 NO VALIDATION CHECK FOR NEW OWNER IN TRANSFEROWNERSHIP // MEDIUM Description In the TransferOwnership function of the blocklistMsgServer, there is a missing validation check to ensure that the new owner is different from the previous owner. Currently, the function allows transferring ownership to the same address as the current owner. The specific issue lies in the following code snippet: func (k blocklistMsgServer) TransferOwnership(goCtx context.Context, msg \*blocklist.MsgTransferOwnership) (\*blocklist.MsgTransferOwnershipResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) owner := k.GetBlocklistOwner(ctx) if owner == "" { return nil, blocklist.ErrNoOwner } if msg.Signer != owner { return nil, errors.Wrapf(blocklist.ErrInvalidOwner, "expected %s, got %s", owner, msg.Signer) } k.SetBlocklistPendingOwner(ctx, msg.NewOwner) return &blocklist.MsgTransferOwnershipResponse{}, ctx.EventManager().EmitTypedEvent(&blocklist.OwnershipTransferStarted{ PreviousOwner: owner, NewOwner: msg.NewOwner, }) } BVSS AO:A/AC:L/AX:L/C:N/I:C/A:N/D:N/Y:N/R:P/S:C (6.3) Recommendation To address this issue, it is recommended to add a validation check in the TransferOwnership function to ensure that the new owner is different from the previous owner. Remediation Plan SOLVED: The Noble team solved the issue by new owner check. Remediation Hash https://github.com/noble-assets/aura/commit/44c811a1f60e7d5975cf27ae5d08aa1d72cf33b9 References noble-assets/aura/x/aura/keeper/msg\_server\_blocklist.go#L32 7.2 LACK OF BLACKLIST CHECK WHEN ADDING BURNERS, PAUSERS, AND OWNERS // MEDIUM Description The provided code for the msgServer in the aura module allows adding burners, pausers, and owners without checking if the addresses are in the blacklist. This can lead to a situation where a blacklisted address can be assigned roles with special privileges, such as burning tokens, pausing the module, or transferring ownership. The specific issues are: 1. In the AddBurner function, the code checks if the signer is the current owner and if the burner address is not already a burner. However, it does not check if the burner address is in the blacklist before adding it as a burner. 2. Similarly, in the AddPauser function, the code checks if the signer is the current owner and if the pauser address is not already a pauser. However, it does not verify if the pauser address is in the blacklist before assigning the pauser role. 3. In the TransferOwnership function, the code allows the current owner to transfer ownership to a new address without checking if the new owner address is in the blacklist. BVSS AO:A/AC:L/AX:L/C:N/I:C/A:N/D:N/Y:N/R:P/S:C (6.3) Recommendation Consider adding a blocklist check on the privileged account additions. Remediation Plan RISK ACCEPTED: The Noble team accepted the risk of the issue. 7.3 PAUSE FUNCTIONALITY DOES NOT AFFECT MINT AND BURN OPERATIONS // MEDIUM Description The current implementation of the pause functionality in the module does not prevent the execution of mint and burn operations. This poses a potential issue, as the purpose of pausing the module is to temporarily halt all critical operations. When the module is paused using the MsgPause message, it is expected that all major operations, including minting and burning, should be suspended until the module is unpaused. However, upon reviewing the code, it is evident that the Mint and Burn functions do not check the paused state of the module before executing their respective operations. This oversight allows users with the appropriate permissions (minters and burners) to continue minting and burning tokens even when the module is meant to be paused. This undermines the effectiveness and purpose of the pause functionality and may lead to unexpected behavior or potential vulnerabilities. func (k msgServer) Mint(goCtx context.Context, msg \*types.MsgMint) (\*types.MsgMintResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) if !k.HasMinter(ctx, msg.Signer) { return nil, types.ErrInvalidMinter } allowance := k.GetMinter(ctx, msg.Signer) if allowance.LT(msg.Amount) { return nil, sdkerrors.Wrapf(types.ErrInsufficientAllowance, "minter %s has an allowance of %s", msg.Signer, allowance.String()) } to, err := sdk.AccAddressFromBech32(msg.To) if err != nil { return nil, sdkerrors.Wrapf(err, "unable to decode account address %s", msg.To) } if !msg.Amount.IsPositive() { return nil, errors.New("amount must be positive") } coins := sdk.NewCoins(sdk.NewCoin(k.Denom, msg.Amount)) err = k.bankKeeper.MintCoins(ctx, types.ModuleName, coins) if err != nil { return nil, sdkerrors.Wrapf(err, "unable to mint to module") } err = k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, to, coins) if err != nil { return nil, sdkerrors.Wrapf(err, "unable to transfer from module to user") } k.SetMinter(ctx, msg.Signer, allowance.Sub(msg.Amount)) // NOTE: The bank module emits an event for us. return &types.MsgMintResponse{}, nil } BVSS AO:A/AC:L/AX:L/C:N/I:C/A:N/D:N/Y:N/R:P/S:C (6.3) Recommendation To address this issue and ensure the integrity of the pause functionality, the following recommendations are proposed: 1. Modify the Mint and Burn functions to check the paused state of the module before executing their operations. If the module is paused, these functions should return an appropriate error indicating that the operation is not allowed during the paused state. Remediation Plan SOLVED: The Noble team has already solved the issue with the adding restricting on the keeper. 7.4 DUPLICATE TRANSACTIONS IN THE MEMPOOL'S DATA STRUCTURES // INFORMATIONAL Description A synchronization issue has been identified in the mempool component of the Noble App Chain, which utilizes CometBFT as its consensus engine. The mempool maintains a list and a map to keep track of outstanding transactions. These two data structures are expected to be in sync at all times, with the map tracking the index of each transaction in the list. However, it has been discovered that under certain circumstances, these data structures can become out of sync, leading to the presence of duplicate transactions in the list. When this issue occurs, the list may contain multiple copies of the same transaction, while the map only tracks a single index. As a result, it becomes impossible to remove all copies of the duplicated transaction from the list, even if the transaction is later committed in a block. The only way to remove the stuck transaction is by restarting the node. Affected Component: CometBFT Affected Versions: The specific version of CometBFT used by the Noble App Chain, as mentioned in the go.mod file: \`\`\` github.com/tendermint/tendermint => github.com/cometbft/cometbft v0.34.27 \`\`\` Score AO:A/AC:L/AX:L/C:N/I:N/A:N/D:N/Y:N/R:N/S:C (0.0) Recommendation To mitigate the impact of this issue, the following workarounds and fixes are recommended: 1. Upgrade CometBFT to the patched versions: For the v0.34.x series, upgrade to v0.34.29 or later. For the v0.37.x series, upgrade to v0.37.2 or later. Remediation Plan ACKNOWLEDGED: The Noble team acknowledged the issue. References cometbft/cometbft 7.5 ASA-2023-002: DEFAULT BLOCKPARAMS.MAXBYTES CONFIGURATION MAY INCREASE BLOCK TIMES AND AFFECT CONSENSUS PARTICIPATION IN THE NOBLE APP CHAIN // INFORMATIONAL Description The Noble App Chain, which utilizes CometBFT as its consensus engine, has been identified to have a default configuration for BlockParams.MaxBytes that may be too large for its specific use case. This default value can potentially increase block times and affect consensus participation when fully utilized by chain participants. It is recommended that the Noble App Chain team consider their specific needs and evaluate the impact of having proposed blocks with the maximum allowed block size, especially on bandwidth usage and block latency. Score AO:A/AC:L/AX:L/C:N/I:N/A:N/D:N/Y:N/R:N/S:C (0.0) Recommendation To mitigate the potential impact of this default configuration, it is recommended that the Noble App Chain team take the following step: 1. Evaluate the specific needs and requirements of the Noble App Chain use case and determine an appropriate value for BlockParams.MaxBytes. Remediation Plan ACKNOWLEDGED: The Noble team acknowledged the issue. References cometbft/cometbft 7.6 ASA-2024-004: DEFAULT EVIDENCE CONFIGURATION PARAMETERS MAY LIMIT WINDOW OF VALIDITY FOR THE NOBLE APP CHAIN // INFORMATIONAL Description The Noble App Chain, which utilizes a vulnerable version of CometBFT as its consensus engine, has been identified to have a default configuration issue. The default values for the EvidenceParams.MaxAgeNumBlocks and EvidenceParams.MaxAgeDuration consensus parameters may not provide sucient coverage for the entire unbonding period of the chain. This could potentially lead to the premature expiration of evidence and allow for unpunished Byzantine behavior if evidence is discovered outside the defined window. Affected Component: CometBFT Affected Versions: The specific version of CometBFT used by the Noble App Chain, as mentioned in the go.mod file: \`\`\` github.com/tendermint/tendermint => github.com/cometbft/cometbft v0.34.27 \`\`\` Score AO:A/AC:L/AX:L/C:N/I:N/A:N/D:N/Y:N/R:N/S:C (0.0) Recommendation It is recommended that chain ecosystems and their maintainers set the consensus parameters EvidenceParams.MaxAgeNumBlocks and EvidenceParams.MaxAgeDuration. Remediation Plan ACKNOWLEDGED: The Noble team acknowledged the issue. References cometbft/cometbft 7.7 POTENTIAL INCONSISTENCY IN BLOCKED ADDRESS HANDLING FOR USDY TOKEN TRANSFERS // INFORMATIONAL Description The current implementation of the SendCoinsFromModuleToAccount function in the Cosmos SDK and the SendRestrictionFn function in the USDY token module may lead to inconsistent behavior when handling blocked addresses during USDY token transfers. The SendCoinsFromModuleToAccount function includes a check using the BlockedAddr function to prevent sending coins to blocked addresses. If the recipient address is blocked, an error is returned, and the transfer is not allowed to proceed. On the other hand, the SendRestrictionFn function performs additional checks specifically for USDY token transfers. It checks if the sender address is blocked using the HasBlockedAddress function only if the transfer is not a minting operation (i.e., not from the module address to a non-module address). Additionally, it checks if the recipient address is blocked using the same HasBlockedAddress function. The inconsistency arises from the fact that the SendCoinsFromModuleToAccount function uses the BlockedAddr function to check for blocked addresses, while the SendRestrictionFn function uses the HasBlockedAddress function. If these two functions have different implementations or BlockedAddress is available on base coin transfers but not USDY, it could lead to inconsistent behavior when handling blocked addresses.Consequently, a blocked address that is allowed to receive funds according to the SendCoinsFromModuleToAccount function might still be blocked by the SendRestrictionFn function, leading to unexpected transfer failures or inconsistent application of blocked address rules. // SendCoinsFromModuleToAccount transfers coins from a ModuleAccount to an AccAddress. // An error is returned if the module account does not exist or if // the recipient address is black-listed or if sending the tokens fails. func (k BaseKeeper) SendCoinsFromModuleToAccount( ctx context.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins, ) error { senderAddr := k.ak.GetModuleAddress(senderModule) if senderAddr == nil { return errorsmod.Wrapf(sdkerrors.ErrUnknownAddress, "module account %s does not exist", senderModule) } if k.BlockedAddr(recipientAddr) { return errorsmod.Wrapf(sdkerrors.ErrUnauthorized, "%s is not allowed to receive funds", recipientAddr) } return k.SendCoins(ctx, senderAddr, recipientAddr, amt) } Score AO:A/AC:L/AX:L/C:N/I:N/A:N/D:N/Y:N/R:P/S:C (0.0) Recommendation Review the implementation of the BlockedAddr function used in the SendCoinsFromModuleToAccount function and the HasBlockedAddress function used in the SendRestrictionFn function. Ensure that both functions have consistent behavior and use the same underlying blocked address list or mechanism. Remediation Plan ACKNOWLEDGED: The Noble team acknowledged the issue. References cosmos/cosmos-sdk/x/bank/keeper/keeper.go#L272 7.8 LACK OF SIMULATION AND FUZZING OF THE MODULE INVARIANT // INFORMATIONAL Description The Noble AppChain system lacks comprehensive CosmosSDK simulations and invariants for its Aura module. More complete use of the simulation feature would make it easier to fuzz test the entire blockchain and help ensure that invariants hold. Score AO:A/AC:L/AX:L/C:N/I:N/A:N/D:N/Y:N/R:P/S:C (0.0) Recommendation Eventually, extend the simulation module to cover all operations that can occur in a real Noble Chain deployment, along with all possible error states, and run it many times before each release. Make sure of the following:- All module operations are included in the simulation module. - The simulation uses some accounts (e.g., between 5 and 20) to increase the likelihood of an interesting state change. - The simulation uses the currencies/tokens that will be used in the production network. - The simulation continues to run when a transaction fails. - All paths of the transaction code are executed. (Enable code coverage to see how often individual lines are executed.) Remediation Plan ACKNOWLEDGED: The Noble team acknowledged the issue. 7.9 MISSING LONG DESCRIPTIONS IN CLI AFFECTS USABILITY AND USER EXPERIENCE // INFORMATIONAL Description The Command Line Interface (CLI) for the module is currently lacking long descriptions, which are available in the Cosmos SDK. Long descriptions provide users with detailed information about the purpose and usage of CLI commands. The absence of these descriptions reduces the overall usability and user experience of the CLI, as users may face diculty in understanding the functionality and proper usage of various commands. Score AO:A/AC:L/AX:L/C:N/I:N/A:N/D:N/Y:N/R:P/S:C (0.0) Recommendation To address the issue of missing long descriptions in the CLI, it is recommended to: Update the CLI to include long descriptions for all commands, following the guidelines and format provided by the Cosmos SDK. Ensure that these descriptions are comprehensive and accurately convey the purpose and usage of each command. Remediation Plan ACKNOWLEDGED: The Noble team acknowledged the issue. References - https://github.com/noble-assets/aura/blob/main/x/aura/client/cli/tx\_blocklist.go#L31 - https://github.com/noble-assets/aura/blob/main/x/aura/client/cli/tx\_blocklist.go#L81 - https://github.com/noble-assets/aura/blob/main/x/aura/client/cli/tx\_blocklist.go#L106 7.10 BLOCKLIST OWNER CAN ADD ITSELF TO THE BLOCKLIST // INFORMATIONAL Description In the current implementation of the AddToBlocklist function in the blocklistMsgServer, there is no check to prevent the blocklist owner from adding itself to the blocklist. This means that the owner can inadvertently or intentionally block their own address, which could lead to unintended consequences and potentially lock them out of performing further blocklist operations. func (k blocklistMsgServer) AddToBlocklist(goCtx context.Context, msg \*blocklist.MsgAddToBlocklist) (\*blocklist.MsgAddToBlocklistResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) owner := k.GetBlocklistOwner(ctx) if owner == "" { return nil, blocklist.ErrNoOwner } if msg.Signer != owner { return nil, errors.Wrapf(blocklist.ErrInvalidOwner, "expected %s, got %s", owner, msg.Signer) } for \_, account := range msg.Accounts { address, err := sdk.AccAddressFromBech32(account) if err != nil { return nil, errors.Wrapf(err, "unable to decode account address %s", account) } k.SetBlockedAddress(ctx, address) } return &blocklist.MsgAddToBlocklistResponse{}, ctx.EventManager().EmitTypedEvent(&blocklist.BlockedAddressesAdded{ Accounts: msg.Accounts, }) } Score AO:A/AC:L/AX:L/C:N/I:N/A:N/D:N/Y:N/R:P/S:C (0.0) Recommendation To prevent the blocklist owner from accidentally or intentionally adding itself to the blocklist, it is recommended to add a validation check in the AddToBlocklist function. Remediation Plan ACKNOWLEDGED: The Noble team acknowledged the issue. References noble-assets/aura/x/aura/keeper/msg\_server\_blocklist.go#L61 8. AUTOMATED TESTING Halborn used automated testing techniques to enhance coverage of certain areas of the scoped component. Among the tools used were staticcheck, gosec, semgrep, unconvert, codeql and nancy. After Halborn verified all the code and scoped structures in the repository and was able to compile them correctly, these tools were leveraged on scoped structures. With these tools, Halborn can statically verify security related issues across the entire codebase. Staticcheck No result. Gosec No result. Errcheck No result. Halborn strongly recommends conducting a follow-up assessment of the project either within six months or immediately following any material changes to the codebase, whichever comes first. This approach is crucial for maintaining the project’s integrity and addressing potential vulnerabilities introduced by code modifications.
---
# Unknown
v. 1.0 Ondo OndoProtocol 26thOctober2022 C o n t e n t s 1C h a n g e l o g7 2I n t r o d u c t i o n8 3P r o j e c t s c o p e9 4M e t h o d o l o g y1 0 5O u r f i n d i n g s1 1 6C r i t i c a l I s s u e s1 2 C V F - 1 2 1 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1 2 7M a j o r I s s u e s1 3 C V F - 1 7 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1 3 C V F - 3 1 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1 3 C V F - 6 8 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1 4 C V F - 1 4 9 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1 4 8M o d e r a t e I s s u e s1 5 C V F - 7 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1 5 C V F - 9 0 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1 5 C V F - 9 1 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1 6 C V F - 9 2 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1 6 C V F - 1 0 4 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1 7 C V F - 1 2 2 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1 7 C V F - 1 3 3 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1 7 9M i n o r I s s u e s1 8 C V F - 1 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1 8 C V F - 2 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1 8 C V F - 3 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1 8 C V F - 4 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1 9 C V F - 5 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1 9 C V F - 6 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1 9 C V F - 8 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 0 C V F - 9 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 0 C V F - 1 0 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 0 C V F - 1 1 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 1 C V F - 1 2 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 1 C V F - 1 3 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 1 C V F - 1 4 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 2 C V F - 1 5 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 2 C V F - 1 6 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 2 C V F - 1 8 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 3 C V F - 1 9 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 3 C V F - 2 0 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 3 C V F - 2 1 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 4 C V F - 2 2 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 4 C V F - 2 3 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 4 C V F - 2 4 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 5 C V F - 2 5 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 5 C V F - 2 6 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 5 C V F - 2 7 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 6 C V F - 2 8 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 6 C V F - 2 9 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 6 C V F - 3 0 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 7 C V F - 3 2 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 7 C V F - 3 3 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 7 C V F - 3 4 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 8 C V F - 3 5 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 8 C V F - 3 6 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 8 C V F - 3 7 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 9 C V F - 3 8 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 9 C V F - 3 9 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 9 C V F - 4 0 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 0 C V F - 4 1 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 0 C V F - 4 2 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 0 C V F - 4 3 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 1 C V F - 4 4 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 1 C V F - 4 5 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 2 C V F - 4 6 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 2 C V F - 4 7 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 3 C V F - 4 8 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 3 C V F - 4 9 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 4 C V F - 5 0 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 4 C V F - 5 1 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 4 C V F - 5 2 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 5 C V F - 5 3 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 5 C V F - 5 4 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 5 C V F - 5 5 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 6 C V F - 5 6 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 6 C V F - 5 7 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 6 C V F - 5 8 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 7 C V F - 5 9 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 7 C V F - 6 0 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 8 C V F - 6 1 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 8 C V F - 6 2 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 8 C V F - 6 3 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 9 C V F - 6 4 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 9 C V F - 6 5 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 9 C V F - 6 6 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 0 C V F - 6 7 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 0 C V F - 6 9 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 0 C V F - 7 0 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 1 C V F - 7 1 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 1 C V F - 7 2 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 2 C V F - 7 3 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 2 C V F - 7 4 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 3 C V F - 7 5 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 3 C V F - 7 6 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 3 C V F - 7 7 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 4 C V F - 7 8 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 4 C V F - 7 9 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 4 C V F - 8 0 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 5 C V F - 8 1 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 5 C V F - 8 2 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 5 C V F - 8 3 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 6 C V F - 8 4 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 6 C V F - 8 5 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 6 C V F - 8 6 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 7 C V F - 8 7 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 7 C V F - 8 8 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 7 C V F - 8 9 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 8 C V F - 9 3 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 8 C V F - 9 4 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 8 C V F - 9 5 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 9 C V F - 9 6 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 9 C V F - 9 7 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 9 C V F - 9 8 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 0 C V F - 9 9 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 0 C V F - 1 0 0 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 0 C V F - 1 0 1 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 1 C V F - 1 0 2 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 1 C V F - 1 0 3 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 1 C V F - 1 0 5 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 2 C V F - 1 0 6 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 2 C V F - 1 0 7 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 2 C V F - 1 0 8 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 3 C V F - 1 0 9 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 3 C V F - 1 1 0 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 3 C V F - 1 1 1 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 4 C V F - 1 1 2 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 4 C V F - 1 1 3 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 4 C V F - 1 1 4 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 5 C V F - 1 1 5 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 5 C V F - 1 1 6 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 6 C V F - 1 1 7 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 6 C V F - 1 1 8 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 6 C V F - 1 1 9 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 7 C V F - 1 2 0 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 7 C V F - 1 2 3 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 8 C V F - 1 2 4 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 8 C V F - 1 2 5 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 8 C V F - 1 2 6 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 9 C V F - 1 2 7 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 9 C V F - 1 2 8 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 9 C V F - 1 2 9 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6 0 C V F - 1 3 0 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6 0 C V F - 1 3 1 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6 0 C V F - 1 3 2 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6 0 C V F - 1 3 4 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6 1 C V F - 1 3 5 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6 1 C V F - 1 3 6 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6 1 C V F - 1 3 7 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6 1 C V F - 1 3 8 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6 2 C V F - 1 3 9 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6 2 C V F - 1 4 0 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6 2 C V F - 1 4 1 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6 3 C V F - 1 4 2 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6 3 C V F - 1 4 3 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6 3 C V F - 1 4 4 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6 4 C V F - 1 4 5 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6 4 C V F - 1 4 6 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6 4 C V F - 1 4 7 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6 5 C V F - 1 4 8 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6 5 C V F - 1 5 0 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6 5 C V F - 1 5 1 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6 6 C V F - 1 5 2 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6 6 C V F - 1 5 3 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6 7 C V F - 1 5 4 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6 7 C V F - 1 5 5 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6 8 C V F - 1 5 6 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6 8 C V F - 1 5 7 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6 9 C V F - 1 5 8 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6 9 C V F - 1 5 9 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7 0 C V F - 1 6 0 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7 0 C V F - 1 6 1 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7 0 C V F - 1 6 2 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7 1 C V F - 1 6 3 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7 1 C V F - 1 6 4 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7 2 C V F - 1 6 5 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7 2 C V F - 1 6 6 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7 3 C V F - 1 6 7 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7 3 C V F - 1 6 8 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7 3 C V F - 1 6 9 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7 4 C V F - 1 7 0 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7 4 C V F - 1 7 1 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7 5 C V F - 1 7 2 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7 5 C V F - 1 7 3 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7 6 C V F - 1 7 4 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7 6 C V F - 1 7 5 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7 7 C V F - 1 7 6 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7 7 C V F - 1 7 7 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7 8 C V F - 1 7 8 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7 8 C V F - 1 7 9 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7 9 C V F - 1 8 0 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7 9 C V F - 1 8 1 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7 9 C V F - 1 8 2 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8 0 C V F - 1 8 3 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8 0 C V F - 1 8 4 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8 0 C V F - 1 8 5 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8 1 C V F - 1 8 6 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8 2 C V F - 1 8 7 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8 2 C V F - 1 8 8 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8 3 C V F - 1 8 9 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8 3 C V F - 1 9 0 .F I X E D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8 3 C V F - 1 9 1 .I N F O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8 4 1C h a n g e l o g #D a t eA u t h o rD e s c r i p t i o n 0 . 12 5 . 1 0 . 2 2A . Z v e r y a n s k a y aI n i t i a l D r a f t 0 . 22 6 . 1 0 . 2 2A . Z v e r y a n s k a y aM i n o r r e v i s i o n 1 . 02 6 . 1 0 . 2 2A . Z v e r y a n s k a y aR e l e a s e 7 2I n t r o d u c t i o n A l l m o d i f i c a t i o n s t o t h i s d o c u m e n t a r e p r o h i b i t e d . V i o l a t o r s w i l l b e p r o s e c u t e d t o t h e f u l l e x t e n t o f t h e U . S . l a w . T h e f o l l o w i n g d o c u m e n t p r o v i d e s t h e r e s u l t o f t h e a u d i t p e r f o r m e d b y A B D K C o n s u l t i n g ( M i k h a i l V l a d i m i r o v a n d D m i t r y K h o v r a t o v i c h ) a t t h e c u s t o m e r r e q u e s t . T h e a u d i t g o a l i s a g e n e r a l r e v i e w o f t h e s m a r t c o n t r a c t s s t r u c t u r e , c r i t i c a l / m a j o r b u g s d e t e c t i o n a n d i s s u i n g t h e g e n e r a l r e c o m m e n d a t i o n s . O n d o F i n a n c e i s a n o p e n , p e r m i s s i o n l e s s , d e c e n t r a l i z e d i n v e s t m e n t b a n k . O n d o ’s c o r e b u s i n e s s i s t o s e r v i c e a n d c o n n e c t v a r i o u s s t a k e h o l d e r s i n t h e e m e r g i n g D e F i e c o s y s t e m - i n c l u d i n g D A O s a n d i n c r e a s i n g l y i n s t i t u t i o n a l a n d m a i n s t r e a m r e t a i l i n v e s t o r s - t h r o u g h f u l l y o n - c h a i n s e r v i c e s . 8 3P r o j e c t s c o p e W e w e r e a s k e d t o r e v i e w : •O r i g i n a l R e p o s i t o r y •F i x R e p o s i t o r y F i l e s : / O n d o R e g i s t r y C l i e n t I n i t i a l i z a b l e . s o l O n d o R e g i s t r y C l i e n t . s o lR e g i s t r y . s o l M u l t i e x . s o l i n t e r f a c e s / I M u l t i e x . s o lI P a i r V a u l t . s o lI R e g i s t r y . s o l I R o l l o v e r . s o lI S A S t r a t e g y . s o lI S i n g l e A s s e t V a u l t . s o l I S t r a t e g y . s o l . s o lI T r a n c h e T o k e n . s o lI W E T H . s o l l i b r a r i e s / O n d o L i b r a r y . s o l s i n g l e / S A S t r a t e g y A l l P a i r V a u l t . s o l S A S t r a t e g y C o n v e x . s o lS A S t r a t e g y R o l l o v e r . s o l S i n g l e A s s e t V a u l t . s o l s t r a t e g i e s / A C o n v e x A u t o c o m p o u n d e r . s o l B a l a n c e r S t r a t e g y . s o lB a s e P a i r L P S t r a t e g y . s o l C o n v e x A u t o c o m - p o u n d e r S t r a t e g y . s o l v e n d o r / b a l a n c e r / I B a l a n c e r V a u l t . s o l v e n d o r / c o n v e x / I B a s e R e w a r d P o o l . s o lI C o n v e x B o o s t e r . s o l v e n d o r / c u r v e / I C u r v e \_ 2 . s o lI C u r v e \_ 3 . s o l 9 4M e t h o d o l o g y T h e m e t h o d o l o g y i s n o t a s t r i c t f o r m a l p r o c e d u r e , b u t r a t h e r a c o l l e c t i o n o f m e t h o d s a n d t a c t i c s t h a t c o m b i n e d d i f f e r e n t l y a n d t u n e d f o r e v e r y p a r t i c u l a r p r o j e c t , d e p e n d i n g o n t h e p r o j e c t s t r u c t u r e a n d u s e d t e c h n o l o g i e s , a s w e l l a s o n w h a t t h e c l i e n t i s e x p e c t i n g f r o m t h e a u d i t . •G e n e r a l C o d e A s s e s s m e n t. T h e c o d e i s r e v i e w e d f o r c l a r i t y , c o n s i s t e n c y , s t y l e , a n d f o r w h e t h e r i t f o l l o w s c o d e b e s t p r a c t i c e s a p p l i c a b l e t o t h e p a r t i c u l a r p r o g r a m m i n g l a n g u a g e u s e d . W e c h e c k i n d e n t a t i o n , n a m i n g c o n v e n t i o n , c o m m e n t e d c o d e b l o c k s , c o d e d u p l i c a t i o n , c o n f u s i n g n a m e s , c o n f u s i n g , i r r e l e v a n t , o r m i s s i n g c o m m e n t s e t c . A t t h i s p h a s e w e a l s o u n d e r s t a n d o v e r a l l c o d e s t r u c t u r e . •E n t i t y U s a g e A n a l y s i s. U s a g e s o f v a r i o u s e n t i t i e s d e f i n e d i n t h e c o d e a r e a n a l y s e d . T h i s i n c l u d e s b o t h : i n t e r n a l u s a g e s f r o m o t h e r p a r t s o f t h e c o d e a s w e l l a s p o t e n t i a l e x t e r n a l u s a g e s . W e c h e c k t h a t e n t i t i e s a r e d e f i n e d i n p r o p e r p l a c e s a n d t h a t t h e i r v i s i b i l i t y s c o p e s a n d a c c e s s l e v e l s a r e r e l e v a n t . A t t h i s p h a s e w e u n d e r s t a n d o v e r a l l s y s t e m a r c h i t e c t u r e a n d h o w d i f f e r e n t p a r t s o f t h e c o d e a r e r e l a t e d t o e a c h o t h e r . •A c c e s s C o n t r o l A n a l y s i s. F o r t h o s e e n t i t i e s , t h a t c o u l d b e a c c e s s e d e x t e r n a l l y , a c c e s s c o n t r o l m e a s u r e s a r e a n a l y s e d . W e c h e c k t h a t a c c e s s c o n t r o l i s r e l e v a n t a n d i s d o n e p r o p e r l y . A t t h i s p h a s e w e u n d e r s t a n d u s e r r o l e s a n d p e r m i s s i o n s , a s w e l l a s w h a t a s s e t s t h e s y s t e m o u g h t t o p r o t e c t . •C o d e L o g i c A n a l y s i s. T h e c o d e l o g i c o f p a r t i c u l a r f u n c t i o n s i s a n a l y s e d f o r c o r r e c t n e s s a n d e f f i c i e n c y . W e c h e c k t h a t c o d e a c t u a l l y d o e s w h a t i t i s s u p p o s e d t o d o , t h a t a l g o r i t h m s a r e o p t i m a l a n d c o r r e c t , a n d t h a t p r o p e r d a t a t y p e s a r e u s e d . W e a l s o c h e c k t h a t e x t e r n a l l i b r a r i e s u s e d i n t h e c o d e a r e u p t o d a t e a n d r e l e v a n t t o t h e t a s k s t h e y s o l v e i n t h e c o d e . A t t h i s p h a s e w e a l s o u n d e r s t a n d d a t a s t r u c t u r e s u s e d a n d t h e p u r p o s e s t h e y a r e u s e d f o r . 1 0 5O u r f i n d i n g s W e f o u n d 1 c r i t i c a l , 4 m a j o r , a n d a f e w l e s s i m p o r t a n t i s s u e s . A l l i d e n t i f i e d C r i t i c a l i s s u e s h a v e b e e n f i x e d . Critical Severity Active Fixed Issues 0 1 Major ActiveFixed 22 Moderate ActiveFixed 0 7 Minor ActiveFixed 1 1 7 6 2 F i x e d 7 2 o u t o f 1 9 1 i s s u e s 1 1 6C r i t i c a l I s s u e s C V F - 1 2 1 .F I X E D •C a t e g o r yF l a w•S o u r c eS i n g l e A s s e t V a u l t . s o l D e s c r i p t i o nI t i s n o t c h e c k e d t h a t t h e p o o l i s n o t y e t r e d e e m e d , s o i t i s p o s s i b l e t o r e d e e m a p o o l s e v e r a l t i m e s . 1 8 3pool .redeemed=true; 1 2 7M a j o r I s s u e s C V F - 1 7 .F I X E D •C a t e g o r yD o c u m e n t a t i o n•S o u r c eR e g i s t r y . s o l D e s c r i p t i o nD e s p i t e t h e n a m e , t h i s f u n c t i o n i s n o t o n l y a b l e t o a d d a n e w s t r a t e g i s t , b u t a l s o c h a n g e t h e n a m e o f a n e x i s t i n g s t r a t e g i s t . R e c o m m e n d a t i o nC o n s i d e r e i t h e r m e n t i o n i n g t h i s f a c t i n t h e d o c u m e n t a t i o n c o m m e n t , o r e x p l i c i t l y f o r b i d a d d i n g t h e s a m e s t r a t e g i s t t w i c e . 7 4functionaddStrategist(address\_strategist,stringcalldata\_name) ↪→external{ C V F - 3 1 .I N F O •C a t e g o r yF l a w•S o u r c e O n d o R e g i s t r y C l i e n t I n i t i a l i z a b l e . s o l D e s c r i p t i o nT h e r e i s n o c h e c k t h a t t h e l e n g r t h s o f t h e “ \_ t o k e n s ” a n d “ \_ a m o u n t s ” a r r a y s a r e t h e s a m e . I n c a s e t h e “ \_ a m o u n t s ” a r r a y i s l o n g e r , e x t r a e l e m e n t a r e s i l e n t l y i g n o r e d . R e c o m m e n d a t i o nC o n s i d e r a d d i n g a n a p p r o p r i a t e c h e c k . C l i e n t C o m m e n tC h e c k e d i n t h e e x t e r n a l f u n c t i o n w h i c h i m p l e m e n t s t h e i n t e r n a l \_ r e s - c u e T o k e n s ( ) f u n c t i o n , w o n ’ t f i x . 6 0function\_rescueTokens(address\[\] calldata\_tokens,uint256\[\]memory ↪→\_amounts) 1 3 C V F - 6 8 .F I X E D •C a t e g o r yF l a w•S o u r c e A C o n v e x A u t o c o m p o u n d e r . s o l D e s c r i p t i o nI t i s n o t c h e c k e d t h a t t h e “ \_ a s s e t s ” a n d “ \_ p a t h s ” a r r a y s h a v e t h e s a m e l e n g t h . I f t h e “ \_ p a t h s ” a r r a y i s l o n g e r t h a n t h e “ \_ a s s e t s ” a r r a y , e x t r a e l e m e n t s a r e s i l e n t l y i g n o r e d . R e c o m m e n d a t i o nC o n s i d e r a d d i n g a p p r o p r i a t e l e n g t h c h e c k . 1 1 4functionsetSwapPaths(address\[\]memory\_assets, SwapPath\[\]memory ↪→\_paths) C V F - 1 4 9 .I N F O •C a t e g o r yS u b o p t i m a l•S o u r c eO n d o L i b r a r y . s o l D e s c r i p t i o nT h i s p e r f o r m s t h r e e c a l l s t o t h e t o k e n c o n t r a c t i n s t e a d o f o n e , w h i c h i s o v e r k i l l i n m o s t c a s e s a n d j u s t w a s t e s g a s . U s u a l l y , s m a r t c o n t r a c t s j u s t o v e r w r i t e t h e c u r r e n t a l l o w a n c e b e f o r e c a l l i n g a c o n t r a c t t h a t n e e d s t o t a k e t o k e n s . I n c a s e t h e w h o l e a l l o w a n c e i s u s e d , t h e r e i s n o n e e d t o s e t t o t o z e r o e x p l i c i t l y . R e c o m m e n d a t i o nC o n s i d e r s i m p l i f y i n g . C l i e n t C o m m e n tG a s c o s t i s a b s o r b e d b y u s , w o n ’ t f i x . 1 4 8uint256newAllowance= token.allowance(address(this), spender) + ↪→value; token.safeApprove(spender, 0); 1 5 0token.safeApprove(spender, newAllowance); 1 4 8M o d e r a t e I s s u e s C V F - 7 .F I X E D •C a t e g o r yF l a w•S o u r c e C o n v e x A u t o c o m p o u n d e r S t r a t e g y . s o l D e s c r i p t i o nT h i s f u n c t i o n i s c a l l a b l e b y a n y o n e . R e c o m m e n d a t i o nC o n s i d e r r e s t r i c t i n g a c c e s s t o i t . 5 6functioninvest( C V F - 9 0 .F I X E D •C a t e g o r yF l a w•S o u r c eS A S t r a t e g y R o l l o v e r . s o l D e s c r i p t i o nT h e s e f u n c t i o n s a r e n o t m a r k e d w i t h t h e “ n o n R e e n t r a n t ” m o d i f i e r , w h i l e t h e y d o u p d a t e s t a t e a f t e r c a l l i n g p o t e n t i a l l y u n t r u s t e d e x t e r n a l c o n t r a c t s a n d t h u s a r e p o t e n - t i a l l y v u l n e r a b l e t o r e e n t r a n c y a t t a c k s . R e c o m m e n d a t i o nC o n s i d e r e t h e r u s i n g t h e “ n o n R e e n t r a n t ” m o d i f i e r f o r t h e s e f u n c t i o n s o r r e f a c t o r i n g t h e i r c o d e t o d o f o l l o w c h e c k → u p d a t e → c a l l e x e c u t i o n o r d e r . 6 5functioninvest( 9 2functionredeem(uint256poolId,bytesmemorydata) 1 5 C V F - 9 1 .F I X E D •C a t e g o r yF l a w•S o u r c eS A S t r a t e g y R o l l o v e r . s o l D e s c r i p t i o nT h e s t a t e i s c h e c k e d b e f o r e c a l l i n g e x t e r n a l c o n t r a c t s , w h i l e u p d a t e d a f t e r - w a r d s . T h i s m a k e s t h e f u n c t i o n p o t e n t i a l l y v u l n e r a b l e t o r e e n t r a n c y a t t a c k . R e c o m m e n d a t i o nC o n s i d e r r e f a c t o r i n g t h e c o d e o r u s i n g t h e “ n o n R e e n t r a n t ” m o d i f i e r . 7 6require(! rolloverInvested\[param.rolloverId\], "rollover invested"); 8 5asset.safeApprove(address(rolloverManager), amount); rolloverManager.deposit(param.rolloverId, param.tranche, amount); rolloverInvested\[param.rolloverId\] =true; C V F - 9 2 .F I X E D •C a t e g o r yF l a w•S o u r c eS A S t r a t e g y R o l l o v e r . s o l D e s c r i p t i o nT h e s t a t e i s c h e c k e d b e f o r e c a l l i n g e x t e r n a l c o n t r a c t s , w h i l e u p d a t e d a f t e r - w a r d s . T h i s m a k e s t h e f u n c t i o n p o t e n t i a l l y v u l n e r a b l e t o r e e n t r a n c y a t t a c k . R e c o m m e n d a t i o nC o n s i d e r r e f a c t o r i n g t h e c o d e o r u s i n g t h e “ n o n R e e n t r a n t ” m o d i f i e r . 1 0 1require(rolloverInvested\[investParam.rolloverId\], "rollover not ↪→invested"); 1 4 4vaultManager.withdraw(investParam.rolloverId, investParam.tranche) ↪→; 1 5 2asset.safeTransfer(msg.sender, amount); 1 5 4rolloverInvested\[investParam.rolloverId\] =false; 1 6 C V F - 1 0 4 .F I X E D •C a t e g o r yS u b o p t i m a l•S o u r c eS A S t r a t e g y C o n v e x . s o l D e s c r i p t i o nT h e f u n c t i o n a c t u a l l y d o e s n ’ t r e t u r n a n y t h i n g f o r t h e f i r s t r e t u r n v a l u e . R e c o m m e n d a t i o nC o n s i d e r e i t h e r r e m o v i n g t h i s r e t u r n v a l u e f r o m t h e f u n c t i o n d e c l a r a - t i o n o r a c t u a l l y r e t u r n i n g s o m e t h i n g f o r i t . 7 1returns(bool,uint256amount) C V F - 1 2 2 .F I X E D •C a t e g o r yS u b o p t i m a l•S o u r c eS i n g l e A s s e t V a u l t . s o l D e s c r i p t i o nT h i s r e a d s a l l t h e d e p o s i t s i n t o t h e m e m o r y , e v e n t h o s e b e f o r e “ f r o m D e - p o s i t I n d e x \[ \_ u s e r \] ” . R e c o m m e n d a t i o nC o n s i d e r l o a d i n g o n l y r e l e v a n t d e p o s i t s . 2 2 3UserDeposit\[\]memorydeposits= userDeposits\[\_user\]; C V F - 1 3 3 .F I X E D •C a t e g o r yF l a w•S o u r c eS A S t r a t e g y A l l P a i r V a u l t . s o l D e s c r i p t i o nT h e s t a t e i s u p d a t e d a f t e r c a l l i n g u n t r u s t e d e x t e r n a l c o n t r a c t s , w h i c h c o u l d m a k e a r e e n t r a n c y a t t a c k p o s s i b l e . R e c o m m e n d a t i o nC o n s i d e r r e f a c t o r i n g t h e c o d e t o d o s t a t e u p d a t e s b e f o r e c a l l i n g u n - t r u s t e d e x t e r n a l c o n t r a c t s , i . e . b e f o r e p e r f o r m i n g t o k e n t r a n s f e r s . 7 4vaultInvested\[param.vaultId\] =true; 1 7 9M i n o r I s s u e s C V F - 1 .F I X E D •C a t e g o r yS u b o p t i m a l•S o u r c e C o n v e x A u t o c o m p o u n d e r S t r a t e g y . s o l D e s c r i p t i o nT h i s i s e q u i v a l e n t t o : p r a g m a s o l i d i t y ^ 0 . 8 . 0 ; .A l s o r e l e v a n t f o r t h e n e x t f i l e s : A C o n v e x A u t o c o m p o u n d e r . s o l , S A S t r a t e g y R o l l o v e r . s o l , S A S t r a t e g y C o n v e x . s o l , S i n - g l e A s s e t V a u l t . s o l , S A S t r a t e g y A l l P a i r V a u l t . s o l , B a s e R e w a r d P o o l . s o l , I C o n v e x B o o s t e r . s o l , I C u r v e \_ 2 . s o l , I S i n g l e A s s e t V a u l t . s o l , I S A S t r a t e g y . s o l , I R o l l o v e r . s o l , I M u l t i e x . s o l . 2pragmasolidity>=0.8.0 <0.9.0; C V F - 2 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c e C o n v e x A u t o c o m p o u n d e r S t r a t e g y . s o l R e c o m m e n d a t i o nT h e t y p e o f t h i s a r g u m e n t s h o u l d b e “ I E R C 2 0 ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 2 3address\_stableAsset, C V F - 3 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c e C o n v e x A u t o c o m p o u n d e r S t r a t e g y . s o l R e c o m m e n d a t i o nT h e t y p e o f t h i s a r g u m e n t s h o u l d b e “ I R e g i s t r y ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 2 4address\_registry, 1 8 C V F - 4 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c e C o n v e x A u t o c o m p o u n d e r S t r a t e g y . s o l R e c o m m e n d a t i o nT h e t y p e o f t h i s a r g u m e n t s h o u l d b e “ I E R C 2 0 \[ \] ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 2 6address\[\]memory\_rewardTokens C V F - 5 .F I X E D •C a t e g o r yP r o c e d u r a l•S o u r c e C o n v e x A u t o c o m p o u n d e r S t r a t e g y . s o l R e c o m m e n d a t i o nI t i s a g o o d p r a c t i c e t o p u t a c o m m e n t i n t o a n e m p t y b l o c k t o e x p l a i n w h y t h e b l o c k i s e m p t y . 3 0{} C V F - 6 .I N F O •C a t e g o r yU n c l e a r b e h a v i o r•S o u r c e C o n v e x A u t o c o m p o u n d e r S t r a t e g y . s o l D e s c r i p t i o nT h i s f u n c t i o n s h o u l d p r o b a b l y e m i t s o m e e v e n t C l i e n t C o m m e n tI t s a f u n c t i o n c a l l e d b y A l l P a i r V a u l t t o a d d a v a u l t i n t h e s t r a t e g y , a n e v e n t i s n o t n e e d e d . 3 8functionaddVault( 1 9 C V F - 8 .F I X E D •C a t e g o r yB a d n a m i n g•S o u r c e C o n v e x A u t o c o m p o u n d e r S t r a t e g y . s o l D e s c r i p t i o nT h e s e m a n t i c s o f t h e r e t u r n e d v a l u e s i s u n c l e a r . R e c o m m e n d a t i o nC o n s i d e r g i v i n g t h e m d e s c r i p t i v e n a m e s . 6 4)externaloverridenonReentrantreturns(uint256,uint256) { 1 1 1)externaloverridenonReentrantreturns(uint256,uint256) { C V F - 9 .F I X E D •C a t e g o r yO v e r f l o w / U n d e r f l o w•S o u r c e C o n v e x A u t o c o m p o u n d e r S t r a t e g y . s o l D e s c r i p t i o nP h a n t o m o v e r f l o w i s p o s s i b l e h e r e , i . e . a s i t u a t i o n w h e n t h e f i n a l c a l c u l a t i o n r e s u l t w o u l d f i t i n t o t h e d e s t i n a t i o n t y p e , w h i l e s o m e i n t e r m e d i a r y c a l c u l a t i o n o v e r f l o w . R e c o m m e n d a t i o nC o n s i d e r u s i n g t h e “ m u l D i v ” f u n c t i o n a s d e s c r i b e d h e r e : h t t p s : / / x n – 2 - m b . c o m / 2 1 / m u l d i v / i n d e x . h t m l o r s o m e o t h e r a p p r o a c h r e s i s t a n t t o p h a n t o m o v e r f l o w . 9 1shares= ( newLpAmounts\* totalSupply) / prevLpAmounts; 1 1 9amount+= \_withdrawLP(i, ( lpAmounts\[i\] \* shares) / totalSupply); C V F - 1 0 .I N F O •C a t e g o r yP r o c e d u r a l•S o u r c e C o n v e x A u t o c o m p o u n d e r S t r a t e g y . s o l D e s c r i p t i o nB r a c k e t s a r e r e d u n d a n t . R e c o m m e n d a t i o nC o n s i d e r r e m o v i n g t h e m . C l i e n t C o m m e n tB r a c k e t s h e l p r e a d a b i l i t y . 9 1shares= ( newLpAmounts\* totalSupply) / prevLpAmounts; 2 0 C V F - 1 1 .I N F O •C a t e g o r yP r o c e d u r a l•S o u r c eR e g i s t r y . s o l D e s c r i p t i o nS p e c i f y i n g a p a r t i c u l a r c o m p i l e r v e r s i o n m a k e s i t h a r d e r t o m i g r a t e t o n e w e r v e r s i o n s .A l s o r e v e n t f o r t h e n e x t f i l e s : I B a l a n c e r V a u l t . s o l , B a s e P a i r L P S t r a t - e g y . s o l , O n d o R e g i s t r y C l i e n t I n i t i a l i z a b l e . s o l , O n d o R e g i s t r y C l i e n t . s o l , M u l t i e x . s o l , B a l - a n c e r S t r a t e g y . s o l , O n d o L i b r a r y . s o l , I W E T H . s o l , I R e g i s t r y . s o l , I S t r a t e g y . s o l , I P a i r V a u l t . s o l , I T r a n c h e T o k e n . s o l . R e c o m m e n d a t i o nC o n s i d e r s p e c i f y i n g “ ^ 0 . 8 . 0 ” . C l i e n t C o m m e n tT h e a s s u m p t i o n s w e h a v e c u r r e n t a r e b a s e d o n 0 . 8 . 3 a n d w h e n w e w a n t t o u p g r a d e , w e w o u l d h a v e t o c o n s i d e r t h e c h a n g e s a n d m a k e t h e m e x p l i c i t . 2pragmasolidity0.8.3; C V F - 1 2 .F I X E D •C a t e g o r yS u b o p t i m a l•S o u r c eR e g i s t r y . s o l D e s c r i p t i o nT h i s v a r i a b l e i s n e v e r r e a d . R e c o m m e n d a t i o nC o n s i d e r r e m o v i n g i t . 2 4addresspayablepublicfallbackRecipient; C V F - 1 3 .I N F O •C a t e g o r yP r o c e d u r a l•S o u r c eR e g i s t r y . s o l D e s c r i p t i o nM o d i f i e r w i t h t h e s a m e n a m e a n d s e m a n t i c s i a l r e a d y d e f i n e d i n t h e “ A c c e s s - C o n t r o l ” b a s e c o n t r a c t . R e c o m m e n d a t i o nC o n s i d e r r e m o v i n g d u p l i c a t e d e f i n i t i o n . C l i e n t C o m m e n tN o t d u p l i c a t e a s w e a r e o n o l d v e r s i o n o f o p e n z e p p e l i n c o n t r a c t s . 2 8modifieronlyRole(bytes32\_role) { require(hasRole(\_role,msg.sender), "Unauthorized: Invalid role"); 3 0\_; } 2 1 C V F - 1 4 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c eR e g i s t r y . s o l R e c o m m e n d a t i o nT h e t y p e o f t h i s a r g u m e n t s h o u l d b e “ I W E T H ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 3 6address\_weth C V F - 1 5 .I N F O •C a t e g o r yS u b o p t i m a l•S o u r c eR e g i s t r y . s o l D e s c r i p t i o nC h e c k s a g a i n s t z e r o a d d r e s s a r e r e d u n d a n t , a s i t i s a n y w a y p o s s i b l e t o t o p a s s a d e a d a d d r e s s a s a n a r g u m e n t . C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x . 3 8require( \_fallbackRecipient!=address(0) &&\_fallbackRecipient!=address( ↪→this), 4 0"Invalid address" ); require(\_governance!=address(0), "Invalid governance address"); require(\_weth!=address(0), "Invalid weth address"); C V F - 1 6 .I N F O •C a t e g o r yS u b o p t i m a l•S o u r c eR e g i s t r y . s o l D e s c r i p t i o nT h i s f u n c t i o n i s a n a l i a s f o r t h e “ h a s R o l e ” f u n c t i o n . R e c o m m e n d a t i o nC o n s i d e r r e m o v i n g i t . C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x . 5 9functionauthorized(bytes32\_role,address\_account) 2 2 C V F - 1 8 .F I X E D •C a t e g o r yU n c l e a r b e h a v i o r•S o u r c eR e g i s t r y . s o l D e s c r i p t i o nT h e s e f u n c t i o n s s h o u l d e m i t s o m e e v e n t s . 8 2functionenableFeatureFlag(bytes32\_featureFlag) 9 3functiondisableFeatureFlag(bytes32\_featureFlag) 1 1 6functiondeleteFeatureFlag(bytes32\_featureFlag) C V F - 1 9 .F I X E D •C a t e g o r yS u b o p t i m a l•S o u r c eR e g i s t r y . s o l D e s c r i p t i o nT h e s e t w o f u n c t i o n s b a s i c a l l y d o t h e s a m e t h i n g . R e c o m m e n d a t i o nC o n s i d e r r e m o v i n g o n e o f t h e m . 9 3functiondisableFeatureFlag(bytes32\_featureFlag) 1 1 6functiondeleteFeatureFlag(bytes32\_featureFlag) C V F - 2 0 .F I X E D •C a t e g o r yU n c l e a r b e h a v i o r•S o u r c eR e g i s t r y . s o l D e s c r i p t i o nT h e s e e v e n t s a r e e m i t t e d e v e n i f n o t h i n g a c t u a l l y c h a n g e d . 1 4 6emitPaused(msg.sender); 1 5 4emitUnpaused(msg.sender); 2 3 C V F - 2 1 .F I X E D •C a t e g o r yD o c u m e n t a t i o n•S o u r c eI B a l a n c e r V a u l t . s o l D e s c r i p t i o nT h e “ p a y a b l e ” m o d i f i e r w a s r e m o v e d f r o m s t r u c t u r e f i e l d s b u t n o t f r o m f r o m f u n c t i o n s . R e c o m m e n d a t i o nC o n s i d e r e x p l a i n i n g t h i s . 1 8 1)externalpayable; 3 0 6)externalpayablereturns(uint256); 3 6 3)externalpayablereturns(int256\[\]memory); C V F - 2 2 .F I X E D •C a t e g o r yD o c u m e n t a t i o n•S o u r c eI B a l a n c e r V a u l t . s o l D e s c r i p t i o nT h i s c o m m e n t i s c o n f u s i n g . R e c o m m e n d a t i o nC o n s i d e r e l a b o r a t i n g a b i t m o r e r e g a r d i n g w h y t h e “ p a y a b l e ” m o d i f i e r w a s r e m o v e d . 2 2 8addressrecipient, // NOTE : payable-> non payable C V F - 2 3 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c eB a s e P a i r L P S t r a t e g y . s o l R e c o m m e n d a t i o nT h e a r g u m e n t t y p e s h o u l d b e “ I R e g i s t r y ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 3 2constructor(address\_registry) OndoRegistryClient(\_registry) {} 2 4 C V F - 2 4 .I N F O •C a t e g o r yP r o c e d u r a l•S o u r c eB a s e P a i r L P S t r a t e g y . s o l R e c o m m e n d a t i o nI t i s a g o o d p r a c t i c e t o p u t a c o m m e n t i n t o a n e m p t y b l o c k t o e x p l a i n w h y t h e b l o c k i s e m p t y . C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x . 3 2constructor(address\_registry) OndoRegistryClient(\_registry) {} C V F - 2 5 .I N F O •C a t e g o r yB a d n a m i n g•S o u r c eB a s e P a i r L P S t r a t e g y . s o l D e s c r i p t i o nT h e s e m a n t i c s o f t h e r e t u r n e d v a l u e s i s u n c l e a r . R e c o m m e n d a t i o nC o n s i d e r g i v i n g t h e m d e s c r i p t i v e n a m e s a n d o r d e s c r i b i n g i n t h e d o c - u m e n t a t i o n c o m m e n t . C l i e n t C o m m e n tA l r e a d y d o c u m e n t e d , w o n ’ t f i x . 6 8returns(IERC20,uint256) C V F - 2 6 .I N F O •C a t e g o r yS u b o p t i m a l•S o u r c eB a s e P a i r L P S t r a t e g y . s o l D e s c r i p t i o nT h i s i m p l i c i t l y a s s u m e s t h e t r a n c h e i s j u n i o r . } e l s e r e v e r t ( ) ; R e c o m m e n d a t i o nC o n s i d e r m a k i n g t h i s a s s u m p t i o n e x p l i c i t l i k e t h i s : e l s e i f ( t r a n c h e = = O L i b . T r a n c h e . J u n i o r ) { . . . C l i e n t C o m m e n tW o n ’ t f i x , o n l y h a v e 2 t r a n c h e s a n d s l i g h t g a s s a v i n g s w i t h c u r r e n t c o d e . 8 9}else{ 2 5 C V F - 2 7 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c e O n d o R e g i s t r y C l i e n t I n i t i a l i z a b l e . s o l R e c o m m e n d a t i o nT h e a r g u m e n t t y p e s h o u l d b e “ I R e g i s t r y ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 2 1function\_\_OndoRegistryClient\_\_initialize(address\_registry) C V F - 2 8 .I N F O •C a t e g o r yS u b o p t i m a l•S o u r c e O n d o R e g i s t r y C l i e n t I n i t i a l i z a b l e . s o l D e s c r i p t i o nT h i s c h e c k i s r e d u n d a n t . I t i s a n y w a y p o s s i b l e t o p a s s a d e a d r e g i s t r y a d - d r e s s . R e c o m m e n d a t i o nC o n s i d e r r e m o v i n g t h i s c h e c k . C l i e n t C o m m e n tW o n ’ t f i x . 2 5require(\_registry!=address(0), "Invalid registry address"); C V F - 2 9 .I N F O •C a t e g o r yS u b o p t i m a l•S o u r c e O n d o R e g i s t r y C l i e n t I n i t i a l i z a b l e . s o l R e c o m m e n d a t i o nI t w o u l d b e m o r e e f f i c i e n t t o c h e c k “ s u p e r . p a u s e d ( ) ” f i r s t a s i t i s c h e a p e r t h a t c h e c k i n g “ r e g i s t r y . p a u s e d ( ) ” . C l i e n t C o m m e n tW e p a u s e f r o m R e g i s t r y n o t R e g i s t r y C l i e n t I n i t i a l i z a b l e , w o n ’ t f i x . 4 3returnregistry.paused() ||super.paused(); 2 6 C V F - 3 0 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c e O n d o R e g i s t r y C l i e n t I n i t i a l i z a b l e . s o l R e c o m m e n d a t i o nT h e t y p e o f t h e “ \_ t o k e n s ” a r g u m e n t s h o u l d b e “ I E R C 2 0 \[ \] ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 6 0function\_rescueTokens(address\[\] calldata\_tokens,uint256\[\]memory ↪→\_amounts) C V F - 3 2 .I N F O •C a t e g o r yS u b o p t i m a l•S o u r c e O n d o R e g i s t r y C l i e n t I n i t i a l i z a b l e . s o l R e c o m m e n d a t i o nI t w o u l d b e m o r e e f f i c i e n t t o p a s s a s i n g l e a r r a y o f s t r u c t s w i t h t w o f i e l d s , i n s t e a d o f t w o p a r a l l e l a r r a y s . T h i s w o u l d a l s o m a k e t h e l e n g t h c h e c k u n n e c e s s a r y . C l i e n t C o m m e n tL e a v i n g a s i s , w o n ’ t f i x . 6 0function\_rescueTokens(address\[\] calldata\_tokens,uint256\[\]memory ↪→\_amounts) C V F - 3 3 .I N F O •C a t e g o r yS u b o p t i m a l•S o u r c e O n d o R e g i s t r y C l i e n t I n i t i a l i z a b l e . s o l R e c o m m e n d a t i o nI t w o u l d b e m o r e e f f i c i e n t t o p a s s a s i n g l e a r r a y o f s t r u c t s w i t h t w o f i e l d s , i n s t e a d o f t w o p a r a l l e l a r r a y s . T h i s w o u l d a l s o m a k e t h e l e n g t h c h e c k u n n e c e s s a r y . C l i e n t C o m m e n tL e a v i n g a s i s , w o n ’ t f i x . 7 3functionrescueTokens(address\[\] calldata\_tokens,uint256\[\]memory ↪→\_amounts) 2 7 C V F - 3 4 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c eO n d o R e g i s t r y C l i e n t . s o l R e c o m m e n d a t i o nT h e a r g u m e n t t y p e s h o u l d b e “ I R e g i s t r y ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 7constructor(address\_registry) { C V F - 3 5 .I N F O •C a t e g o r yP r o c e d u r a l•S o u r c eM u l t i e x . s o l D e s c r i p t i o nT h i s c o m m e n t s e e m s i r r e l e v a n t . R e c o m m e n d a t i o nC o n s i d e r r e m o v i n g i t . C l i e n t C o m m e n tK e e p i n g c o m m e n t , w o n ’ t f i x . 9\* @noticeSendall fee directlyto creator C V F - 3 6 .F I X E D •C a t e g o r yP r o c e d u r a l•S o u r c eB a l a n c e r S t r a t e g y . s o l R e c o m m e n d a t i o nT h e s e v a r i a b l e s s h o u l d b e d e c l a r e d a s i m m u t a b l e . 2 8IBalancerVaultpublicbalVault; 3 3addresspublicbalPool; 2 8 C V F - 3 7 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c eB a l a n c e r S t r a t e g y . s o l R e c o m m e n d a t i o nT h e t y p e o f t h i s v a r i a b l e s h o u l d b e “ I E R C 2 0 ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 3 3addresspublicbalPool; C V F - 3 8 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c eB a l a n c e r S t r a t e g y . s o l R e c o m m e n d a t i o nT h e t y p e o f t h i s a r g u m e n t s h o u l d b e “ I R e g i s t r y ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 4 5address\_registry, C V F - 3 9 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c eB a l a n c e r S t r a t e g y . s o l R e c o m m e n d a t i o nT h e t y p e o f t h i s a r g u m e n t s h o u l d b e “ I B a l a n c e r V a u l t ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 4 6address\_balVault, 2 9 C V F - 4 0 .F I X E D •C a t e g o r yS u b o p t i m a l•S o u r c eB a l a n c e r S t r a t e g y . s o l R e c o m m e n d a t i o nS h o u l d b e “ ! = ” i n s t e a d o f “ > ” , a s u s i n g “ > ” f o r a d d r e s s e s l o o k s w e i r d . 5 3require(balPool>address(0), "Invalid Pool Id");// Balancerpool ↪→addressis a partof poolid , so , shouldcheckhere . C V F - 4 1 .I N F O •C a t e g o r yU n c l e a r b e h a v i o r•S o u r c eB a l a n c e r S t r a t e g y . s o l D e s c r i p t i o nT h e s e f u n c t i o n s s h o u l d e m i t s o m e e v e n t s . C l i e n t C o m m e n tW o n ’ t f i x . 6 7functionaddVault( 1 3 9functionaddLp(uint256\_vaultId,uint256\_amount) 1 5 7functionremoveLp( 3 8 3functionrebalanceIncomes( C V F - 4 2 .F I X E D •C a t e g o r yS u b o p t i m a l•S o u r c eB a l a n c e r S t r a t e g y . s o l D e s c r i p t i o nT h e e x p r e s s i o n “ v a u l t s \[ \_ v a u l t I d \] ” i s c a l c u l a t e d t w i c e . R e c o m m e n d a t i o nC o n s i d e r c a l c u l a t i n g o n c e a n d r e u s i n g . 7 3address(vaults\[\_vaultId\].origin) ==address(0), 8 3Vaultstoragevault= vaults\[\_vaultId\]; 3 0 C V F - 4 3 .I N F O •C a t e g o r yS u b o p t i m a l•S o u r c eB a l a n c e r S t r a t e g y . s o l R e c o m m e n d a t i o nT h i s c h e c k m a k e s t h e “ \_ s e n i o r T o k e n ” a n d t h e “ \_ j u n i o r | T o k e n ” a r g u - m e n t s r e d u n d a n t . I t w o u l d b e e n o u g h t o j u s t p a s s a b o o l e a n a r g u m e n t t e l l i n g w h e t h e r t o k e n o r d e r i s s t r a i g h t o r r e v e r s e d . C l i e n t C o m m e n tW o n ’ t f i x 7 8require( (tokenA== \_seniorToken&& tokenB== \_juniorToken) || 8 0(tokenB== \_seniorToken&& tokenA== \_juniorToken), "Unsupported vault" ); C V F - 4 4 .I N F O •C a t e g o r yR e a d a b i l i t y•S o u r c eB a l a n c e r S t r a t e g y . s o l R e c o m m e n d a t i o nC o n s i d e r g i v i n g d e s c r i p t i v e n a m e s t o t h e r e t u r n e d v a l u e s f o r r e a d a b i l - i t y . C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x 1 0 6uint256, uint256, IERC20 1 2 7returns(uint256,uint256) 3 1 C V F - 4 5 .I N F O •C a t e g o r yP r o c e d u r a l•S o u r c eB a l a n c e r S t r a t e g y . s o l D e s c r i p t i o nU s u a l l y , c o n t r a c t s j u s t o v e r w r i t e t h e n e w a l l o w a n c e , r a t h e r t h a n i n c r e a s e i t . R e c o m m e n d a t i o nC o n s i d e r d o i n g s o . C l i e n t C o m m e n tW o n ’ t f i x . 2 0 3tokenSenior.ondoSafeIncreaseAllowance(address(balVault), ↪→\_totalSenior); tokenJunior.ondoSafeIncreaseAllowance(address(balVault), ↪→\_totalJunior); 3 0 0IERC20(balPool). ondoSafeIncreaseAllowance(address(balVault), bptIn); 5 0 7\_tokenIn.ondoSafeIncreaseAllowance(address(balVault), \_amountIn); 5 5 0\_tokenIn.ondoSafeIncreaseAllowance(address(balVault), \_maxAmountIn); C V F - 4 6 .F I X E D •C a t e g o r yS u b o p t i m a l•S o u r c eB a l a n c e r S t r a t e g y . s o l R e c o m m e n d a t i o nT h e s e l i n e s c o u l d b e s i m p l i f i e d u s i n g t h e “ - = ” o p e r a t o r . 2 4 2seniorInvested= seniorInvested- tokenSenior.balanceOf(address(this ↪→)); juniorInvested= juniorInvested- tokenJunior.balanceOf(address(this ↪→)); 3 2 C V F - 4 7 .I N F O •C a t e g o r yS u b o p t i m a l•S o u r c eB a l a n c e r S t r a t e g y . s o l D e s c r i p t i o nT h e r e i s n o c h e c k t h a t t h e v a u l t i s n o t y e t i n v e s t e d , s o t h i s c o u l d o v e r w r i t e t h e c u r r e n t s h a r e s v a l u e . R e c o m m e n d a t i o nC o n s i d e r a d d i n g a n a p p r o p r i a t e c h e c k . C l i e n t C o m m e n tI n c o r r e c t s u g g e s t i o n , w o n ’ t f i x . 2 5 3vault.shares= bptOut; C V F - 4 8 .F I X E D •C a t e g o r yP r o c e d u r a l•S o u r c eB a l a n c e r S t r a t e g y . s o l D e s c r i p t i o nT h e e x p l i c i t i n i t i a l i z a t i o n i s r e d u n d a n t . A c c o r d i n g t o t h e d o c u m e n t a t i o n , e l - e m e n t s o f a r r a y s , a l l o c a t e d i n t h e m e m o r y , a r e i n i t i a l i z e d w i t h d e f a u l t v a l u e : h t t p s : / / - d o c s . s o l i d i t y l a n g . o r g / e n / v 0 . 8 . 1 2 / t y p e s . h t m l # a l l o c a t i n g - m e m o r y - a r r a y s F o r t h e “ u i n t 2 5 6 ” t y p e , d e f a u l t v a l u e i s z e r o . 3 0 3// / @NOTEneedto initialize??? yes , the memorymay or may not be ↪→zeroedout . (amountsOut\[0\],amountsOut\[1\]) = (0, 0); 3 3 C V F - 4 9 .I N F O •C a t e g o r yS u b o p t i m a l•S o u r c eB a l a n c e r S t r a t e g y . s o l D e s c r i p t i o nI n c r e a s i n g a l l o w a n c e i n s t e a d o f t r a n s f e r r i n g t o k e n s l o o k s w e i r d . A l s o , i t c o n - s u m e s m o r e g a s t h a n n o r m a l t o k e n t r a n s f e r . R e c o m m e n d a t i o nC o n s i d e r j u s t t r a n s f e r r i n g t o k e n s , i n s t e a d o f i n c r e a s i n g a l l o w a n c e . C l i e n t C o m m e n tW o n ’ t f i x . 3 6 0tokenSenior.ondoSafeIncreaseAllowance( msg.sender, seniorReceived+ vault.seniorExcess ); tokenJunior.ondoSafeIncreaseAllowance( msg.sender, juniorReceived+ vault.juniorExcess ); C V F - 5 0 .I N F O •C a t e g o r yS u b o p t i m a l•S o u r c eB a l a n c e r S t r a t e g y . s o l R e c o m m e n d a t i o nC o n s i d e r a l s o l o g g i n g t h e n u m b e r o f n e w l y a c c r u e d t o k e n s C l i e n t C o m m e n tR e l e v a n t i n f o a l r e a d y l o g g e d f r o m A l l P a i r r e d e e m e v e n t , w o n ’ t f i x . 3 6 8emitRedeem(\_vaultId); C V F - 5 1 .I N F O •C a t e g o r yR e a d a b i l i t y•S o u r c eB a l a n c e r S t r a t e g y . s o l R e c o m m e n d a t i o nS h o u l d b e “ e l s e i f ’ f o r r e a d a b i l i t y . C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x . 3 9 2if(\_seniorReceived> \_seniorExpected) { 3 4 C V F - 5 2 .I N F O •C a t e g o r yR e a d a b i l i t y•S o u r c eB a l a n c e r S t r a t e g y . s o l D e s c r i p t i o nT h e c o d e b e l o w l o o k s l i k e i t i s a l w a y s e x e c u t e d , w h i l e i t i s e x e c u t e d o n l y w h e n \_ s e n i o r R e c e i v e r < \_ s e n i o r E x p e c t e d . R e c o m m e n d a t i o nC o n s i d e r p u t t i n g t h e c o d e b e l o w i n t o a n e x p l i c i t “ e l s e ” b r a n c h f o r r e a d - a b i l i t y . C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x . 4 0 4} C V F - 5 3 .I N F O •C a t e g o r yR e a d a b i l i t y•S o u r c eB a l a n c e r S t r a t e g y . s o l D e s c r i p t i o nT h e c o d e b e l o w l o o k s l i k e i t i s a l w a y s e x e c u t e d , w h i l e i t i s e x e c u t e d o n l y w h e n t h e r e c e i v e d j u n i o r a m o u n t i s e n o u g h t o f u l f i l l t h e s e n i o r e x p e c t a t i o n . R e c o m m e n d a t i o nC o n s i d e r p u t t i n g t h e c o d e b e l o w i n t o a n e x p l i c i t “ e l s e ” b r a n c h f o r r e a d - a b i l i t y . C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x . 4 2 3} C V F - 5 4 .F I X E D •C a t e g o r yO v e r f l o w / U n d e r f l o w•S o u r c eB a l a n c e r S t r a t e g y . s o l D e s c r i p t i o nT h i s c o n v e r s i o n l o o k s l i k e u n d e r f l o w i s p o s s i b l e h e r e , a n d t h e c o d e r e l i e s o n k n o w l e d g e a b o u t h o w b a l a n c e r w o r k s . R e c o m m e n d a t i o nC o n s i d e r u s i n g s a f e c o n v e r s i o n t o n o t r e l y o n e x t e r n a l c o d e . 4 7 8amountOut=uint256( 3 5 C V F - 5 5 .I N F O •C a t e g o r yS u b o p t i m a l•S o u r c eB a l a n c e r S t r a t e g y . s o l D e s c r i p t i o nT h e s e f u n c t i o n s a r e v e r y s i m i l a r . R e c o m m e n d a t i o nC o n s i d e r m e r g i n g t h e m i n t o o n e f u n c t i o n o r e x t r a c t i n g c o m m o n c o d e t o a u t i l i t y f u n c t i o n . C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x . 5 0 0functionswapExactIn( 5 4 3functionswapExactOut( C V F - 5 6 .F I X E D •C a t e g o r yS u b o p t i m a l•S o u r c e A C o n v e x A u t o c o m p o u n d e r . s o l D e s c r i p t i o nT h i s i m p o r t i s n o t u s e d . 1 4import"contracts/interfaces/IRollover.sol"; C V F - 5 7 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c e A C o n v e x A u t o c o m p o u n d e r . s o l R e c o m m e n d a t i o nT h e t y p e o f t h i s f i e l d s h o u l d b e “ I U n i s w a p V 2 R o u t e r ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e 2 3addressrouter; 3 6 C V F - 5 8 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c e A C o n v e x A u t o c o m p o u n d e r . s o l R e c o m m e n d a t i o nT h e t y p e o f t h i s f i e l d s h o u l d b e “ I E R C 2 0 \[ \] ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e 2 4address\[\] path ; C V F - 5 9 .I N F O •C a t e g o r yS u b o p t i m a l•S o u r c e A C o n v e x A u t o c o m p o u n d e r . s o l D e s c r i p t i o nH a r d c o d i n g M a i n n e t a d d r e s s e s i s a b a d p r a c t i c e a s i t m a k e s i t h a r d e r t o t e s t c o n t r a c t s . R e c o m m e n d a t i o nC o n s i d e r p a s s i n g t h e a d d r e s s e s a s c o n s t r u c t o r a r g u m e n t s a n d s t o r i n g i n i m m u t a b l e v a r i a b l e s . C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x 3 7IERC20(0 x6c3F90f043a72FA612cbac8115EE7e52BDe6E490); 3 9ICurve\_3(0 xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7); 4 2IConvexBooster(0 xF403C135812408BFbE8713b5A23a04b3D48AAE31); addresspublicconstantDAI = 0 ↪→x6B175474E89094C44Da98b954EedeAC495271d0F; addresspublicconstantUSDC= 0 ↪→xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; addresspublicconstantUSDT= 0 ↪→xdAC17F958D2ee523a2206206994597C13D831ec7; 3 7 C V F - 6 0 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c e A C o n v e x A u t o c o m p o u n d e r . s o l R e c o m m e n d a t i o nT h e t y p e o f t h e s e c o n s t a n t s s h o u l d b e “ I E R C 2 0 ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 4 3addresspublicconstantDAI = 0 ↪→x6B175474E89094C44Da98b954EedeAC495271d0F; addresspublicconstantUSDC= 0 ↪→xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; addresspublicconstantUSDT= 0 ↪→xdAC17F958D2ee523a2206206994597C13D831ec7; C V F - 6 1 .I N F O •C a t e g o r yD o c u m e n t a t i o n•S o u r c e A C o n v e x A u t o c o m p o u n d e r . s o l D e s c r i p t i o nT h e s e m a n t i c s o f t h e k e y s i n t h i s m a p p i n g i s u n c l e a r . R e c o m m e n d a t i o nC o n s i d e r d o c u m e n t i n g . C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x . 5 0mapping(uint256=>uint256)publicbalanceOf; 5 6mapping(address=> SwapPath)publicswapPaths; C V F - 6 2 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c e A C o n v e x A u t o c o m p o u n d e r . s o l R e c o m m e n d a t i o nT h e t y p e o f t h i s v a r i a b l e s h o u l d b e “ I E R C 2 0 ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 5 5address\[\]publicrewardTokens; 3 8 C V F - 6 3 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c e A C o n v e x A u t o c o m p o u n d e r . s o l R e c o m m e n d a t i o nT h e k e y t y p e f o r t h i s m a p p i n g s h o u l d b e “ I E R C 2 0 ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 5 6mapping(address=> SwapPath)publicswapPaths; C V F - 6 4 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c e A C o n v e x A u t o c o m p o u n d e r . s o l R e c o m m e n d a t i o nT h e t y p e o f t h i s a r g u m e n t s h o u l d b e “ I E R C 2 0 ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 6 4address\_stableAsset, C V F - 6 5 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c e A C o n v e x A u t o c o m p o u n d e r . s o l R e c o m m e n d a t i o nT h e t y p e o f t h i s a r g u m e n t s h o u l d b e “ I R e g i s t r y ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 6 5address\_registry, 3 9 C V F - 6 6 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c e A C o n v e x A u t o c o m p o u n d e r . s o l R e c o m m e n d a t i o nT h e t y p e o f t h i s a r g u m e n t s h o u l d b e “ I E R C 2 0 \[ \] ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 6 7address\[\]memory\_rewardTokens C V F - 6 7 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c e A C o n v e x A u t o c o m p o u n d e r . s o l R e c o m m e n d a t i o nT h e s e i n d e x e s s h o u l d b e n a m e d c o n s t a n t s . C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x . 7 3stableAssetCurveIndex= 0; 7 5stableAssetCurveIndex= 1; 7 7stableAssetCurveIndex= 2; C V F - 6 9 .I N F O •C a t e g o r yS u b o p t i m a l•S o u r c e A C o n v e x A u t o c o m p o u n d e r . s o l R e c o m m e n d a t i o nI t w o u l d b e m o r e e f f i c i e n t t o p a s s a s i n g l e a r r a y o f s t r u c t s w i t h t w o f i e l d s i n s t e a d o f t w o p a r a l l e l a r r a y s . T h i s w o u l d a l s o m a k e t h e l e n g t h c h e c k u n n e c e s s a r y . C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x 1 1 4functionsetSwapPaths(address\[\]memory\_assets, SwapPath\[\]memory ↪→\_paths) 4 0 C V F - 7 0 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c e A C o n v e x A u t o c o m p o u n d e r . s o l R e c o m m e n d a t i o nT h e t y p e o f t h e “ \_ a s s e t s ” a r r a y s h o u l d b e “ I E R C 2 0 ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 1 1 4functionsetSwapPaths(address\[\]memory\_assets, SwapPath\[\]memory ↪→\_paths) C V F - 7 1 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c e A C o n v e x A u t o c o m p o u n d e r . s o l R e c o m m e n d a t i o nT h e a r g u m e n t t y p e s h o u l d b e “ I E R C 2 0 \[ \] ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 1 2 7functionsetRewardTokens(address\[\]memory\_rewardTokens) 4 1 C V F - 7 2 .I N F O •C a t e g o r yU n c l e a r b e h a v i o r•S o u r c e A C o n v e x A u t o c o m p o u n d e r . s o l D e s c r i p t i o nT h e s e f u n c t i o n s s h o u l d p r o b a b l y e m i t s o m e e v e n t s C l i e n t C o m m e n tF i n e a s i s , w o n ’ t f i x . 1 2 7functionsetRewardTokens(address\[\]memory\_rewardTokens) 1 4 8functioncompound()externalisAuthorized(OLib .STRATEGIST\_ROLE) { 1 6 1functionclaim()publicisAuthorized(OLib .STRATEGIST\_ROLE) { 1 7 1functionswapRewardTokensToStableAsset() 1 8 4functionsplitAndDepositConvex() C V F - 7 3 .F I X E D •C a t e g o r yO v e r f l o w / U n d e r f l o w•S o u r c e A C o n v e x A u t o c o m p o u n d e r . s o l D e s c r i p t i o nP h a n t o m o v e r f l o w i s p o s s i b l e h e r e , i . e . a s i t u a t i o n w h e n t h e f i n a l c a l c u l a t i o n r e s u l t w o u l d f i t i n t o t h e d e s t i n a t i o n t y p e , w h i l e s o m e i n t e r m e d i a r y c a l c u l a t i o n o v e r f l o w . R e c o m m e n d a t i o nC o n s i d e r u s i n g t h e “ m u l D i v ” f u n c t i o n a s d e s c r i b e d h e r e : h t t p s : / / x n – 2 - m b . c o m / 2 1 / m u l d i v / i n d e x . h t m l 1 9 9(total3CRVAmount\* setting.allocPoints) / totalAllocPoints 4 2 C V F - 7 4 .I N F O •C a t e g o r yP r o c e d u r a l•S o u r c e A C o n v e x A u t o c o m p o u n d e r . s o l R e c o m m e n d a t i o nI t i s a g o o d p r a c t i c e w h e n p a s s i n g a b o o l e a n l i t e r a l a s a n a r g u m e n t t o p u t t h e a r g u m e n t n a m e a s a c o m m e n t f o r r e a d a b i l i t y . C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x . 2 0 3CONVEX\_BOOSTER.deposit(setting.cvxPID, newLpAmount,true); C V F - 7 5 .F I X E D •C a t e g o r yS u b o p t i m a l•S o u r c e A C o n v e x A u t o c o m p o u n d e r . s o l D e s c r i p t i o nA p p r o v i n g t w i c e b e f o r e e a c h s w a p i s w a s t e o f g a s . R e c o m m e n d a t i o nC o n s i d e r a p p r o v i n g t h e m a x i m u m a m o u n t o n l y o n c e . 2 1 5IERC20(rewardAsset). safeApprove(data.router, 0); IERC20(rewardAsset). safeApprove(data.router, amount); C V F - 7 6 .F I X E D •C a t e g o r yS u b o p t i m a l•S o u r c e A C o n v e x A u t o c o m p o u n d e r . s o l D e s c r i p t i o nT h i s i s r e d u n d a n t f o r m o s t o f t h e t o k e n s , b u t d o e s c o n s u m e e x t r a g a s . R e c o m m e n d a t i o nC o n s i d e r n o t d o i n g t h i s w h e n n o t n e e d e d . F o r e x a m p l e . c o n s i d e r a d d i n g a p e r - t o k e n f l a g t e l l i n g w h e t h e r t h i s a d d i t i o n a l “ a p p r o v e ” c a l l i s n e e d e d f o r t h e t o k e n . 2 1 5IERC20(rewardAsset). safeApprove(data.router, 0); 4 3 C V F - 7 7 .I N F O •C a t e g o r yS u b o p t i m a l•S o u r c e A C o n v e x A u t o c o m p o u n d e r . s o l R e c o m m e n d a t i o nT h i s c o d e c o u l d b e s i m p l i f i e d u s i n g a n a r r a y l i t e r a l . C l i e n t C o m m e n tW o n ’ t f i x . 2 2 8uint256\[3\]memoryamounts; amounts\[0\] =IERC20(DAI ). balanceOf(address(this)); 2 3 0amounts\[1\] =IERC20(USDC ). balanceOf(address(this)); amounts\[2\] =IERC20(USDT ). balanceOf(address(this)); C V F - 7 8 .F I X E D •C a t e g o r yF l a w•S o u r c e A C o n v e x A u t o c o m p o u n d e r . s o l D e s c r i p t i o nI t i s n o t c h e c k e d t h a t t h e s e c o n d t o k e n i s “ T H R E E \_ C R V \_ L P ” . R e c o m m e n d a t i o nC o n s i d e r a d d i n g s u c h c h e c k . 2 5 3}else{ 2 8 1}else{ C V F - 7 9 .F I X E D •C a t e g o r yO v e r f l o w / U n d e r f l o w•S o u r c e A C o n v e x A u t o c o m p o u n d e r . s o l D e s c r i p t i o nT h i s c o n v e r s i o n l o o k s l i k e i t c o u l d c a u s e o v e r f l o w . R e c o m m e n d a t i o nC o n s i d e r u s i n g a s m a l l e r t y p e f o r “ s t a b l e A s s e t C u r v e I n d e x ” , s u c h a s “ u i n t 8 ” t o m a k e t h i s c o n v e r s i o n s a f e . 2 9 1int128(stableAssetCurveIndex), 4 4 C V F - 8 0 .F I X E D •C a t e g o r yS u b o p t i m a l•S o u r c e A C o n v e x A u t o c o m p o u n d e r . s o l D e s c r i p t i o nH e r e i m p l i c i t u n d e r f l o w c h e c k s a r e u s e d t o e n f o r c e b u s i n e s s - l e v e l c o n - s t r a i n t s . T h i s i s a b a d p r a c t i c e a s i t m a k e s c o d e h a r d e r t o r e a d a n d m o r e f r a g i l e . R e c o m m e n d a t i o nC o n s i d e r e x p l i c i t l y c h e c k i n g t h a t t h e b a l a n c e i s s u f f i c i e n t . 3 0 7balanceOf\[poolId\] -=amount; totalSupply-= amount; C V F - 8 1 .F I X E D •C a t e g o r yP r o c e d u r a l•S o u r c eS A S t r a t e g y R o l l o v e r . s o l R e c o m m e n d a t i o nT h e t y p e o f t h i s f i e l d s h o u l d b e a e n u m . 2 3uint256redeemType; // 0: redeemfromrollover, 1: redeemfrom ↪→allPairVault C V F - 8 2 .F I X E D •C a t e g o r yD o c u m e n t a t i o n•S o u r c eS A S t r a t e g y R o l l o v e r . s o l D e s c r i p t i o nT h e s e m a n t i c s o f t h e k e y s i n t h e s e m a p p i n g s i s u n c l e a r . R e c o m m e n d a t i o nC o n s i d e r d o c u m e n t i n g . 3 1mapping(uint256=>bool)publicrolloverInvested; mapping(uint256=>uint256)publicrolloverExcees; mapping(uint256=>uint256)publicrolloverRedeemVaultId; mapping(uint256=> InvestParam)publicinvestParams; 4 5 C V F - 8 3 .F I X E D •C a t e g o r yS u b o p t i m a l•S o u r c eS A S t r a t e g y R o l l o v e r . s o l R e c o m m e n d a t i o nI t w o u l d b e m o r e e f f i c i e n t t o m e r g e t h e s e t h r e e m a p p i n g s i n t o a s i n g l e m a p p i n g w h o s e k e y s a r e r o l l o v e r I D s a n d v a l u e s a r e s t r u c t s o f t h r e e f i e l d s e n c a p s u l a t i n g t h e v a l u e s o f t h e o r i g i n a l m a p p i n g s . 3 1mapping(uint256=>bool)publicrolloverInvested; mapping(uint256=>uint256)publicrolloverExcees; mapping(uint256=>uint256)publicrolloverRedeemVaultId; C V F - 8 4 .F I X E D •C a t e g o r yB a d d a t a t y p e•S o u r c eS A S t r a t e g y R o l l o v e r . s o l R e c o m m e n d a t i o nT h e “ r o l l o v e r I d ” p a r a m e t e r s h o u l d b e i n d e x e d . 3 6eventInvest(uint256rolloverId, OLib .Tranchetranche,uint256 ↪→amount); eventRedeem(uint256rolloverId, OLib .Tranchetranche,uint256 ↪→amount); C V F - 8 5 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c eS A S t r a t e g y R o l l o v e r . s o l R e c o m m e n d a t i o nT h e t y p e o f t h i s a r g u m e n t s h o u l d b e “ I S i n g l e A s s e t V a u l t ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 4 7address\_singleAssetVault, 4 6 C V F - 8 6 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c eS A S t r a t e g y R o l l o v e r . s o l R e c o m m e n d a t i o nT h e t y p e o f t h i s a r g u m e n t s h o u l d b e “ I P a i r V a u l t ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 4 8address\_vault, C V F - 8 7 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c eS A S t r a t e g y R o l l o v e r . s o l R e c o m m e n d a t i o nT h e t y p e o f t h i s a r g u m e n t s h o u l d b e “ I R o l l o v e r ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 4 9address\_rollover, C V F - 8 8 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c eS A S t r a t e g y R o l l o v e r . s o l R e c o m m e n d a t i o nT h e t y p e o f t h i s a r g u m e n t s h o u l d b e “ I R e g i s t r y ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 5 0address\_registry 4 7 C V F - 8 9 .I N F O •C a t e g o r yS u b o p t i m a l•S o u r c eS A S t r a t e g y R o l l o v e r . s o l R e c o m m e n d a t i o nT h e s e c h e c k s a r e r e d u n d a n t , a s i t i s a n y w a y p o s s i b l e t o p a s s a d e a d a d d r e s s a s a n a r g u m e n t . C l i e n t C o m m e n tK e e p i n g c h e c k s , w o n ’ t f i x . 5 2require(\_singleAssetVault!=address(0), "Invalid asset vault"); require(\_vault!=address(0), "Invalid AllPairVault"); require(\_rollover!=address(0), "Invalid RolloverVault"); C V F - 9 3 .F I X E D •C a t e g o r yB a d d a t a t y p e•S o u r c eS A S t r a t e g y R o l l o v e r . s o l R e c o m m e n d a t i o n“ 0 ” a n d “ 1 ” h e r e s h o u l d b e n a m e d c o n s t a n t s . 1 1 0if(redeemParam.redeemType== 0) { 1 3 3}elseif(redeemParam.redeemType== 1) { C V F - 9 4 .F I X E D •C a t e g o r yS u b o p t i m a l•S o u r c eS A S t r a t e g y R o l l o v e r . s o l D e s c r i p t i o nT h e w i t h d r a w n b a l a n c e i s r e t u r n e d f r o m t h e “ w i t h d r a w ” f u n c t i o n c a l l . N o n e e d t o c a l c u l a t e i t f r o m t h e t o k e n b a l a n c e s . R e c o m m e n d a t i o nC o n s i d e r e i t h e r u s i n g t h e r e t u r n e d v a l u e o r e x p l a i n i n g i n a c o m m e n t w h y t h e r e t u r n e d v a l u e c a n n o t b e t r u s t e d . 1 2 4uint256balanceBeforeWithdraw= asset.balanceOf(address(this)); 1 3 1asset.balanceOf(address(this)) - balanceBeforeWithdraw; 4 8 C V F - 9 5 .F I X E D •C a t e g o r yS u b o p t i m a l•S o u r c eS A S t r a t e g y R o l l o v e r . s o l R e c o m m e n d a t i o nT h e w i t h d r a w n b a l a n c e i s r e t u r n e d f r o m t h e “ w i t h d r a w ” f u n c t i o n c a l l . N o n e e d t o c a l c u l a t e i t f r o m t h e t o k e n v a l a n c e s . 1 4 2amount= asset.balanceOf(address(this)); 1 4 7amount= asset.balanceOf(address(this)) -amount; C V F - 9 6 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c eS A S t r a t e g y C o n v e x . s o l R e c o m m e n d a t i o nT h e t y p e o f t h i s a r g u m e n t s h o u l d b e “ I E R C 2 0 ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 2 0address\_stableAsset, C V F - 9 7 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c eS A S t r a t e g y C o n v e x . s o l R e c o m m e n d a t i o nT h e t y p e o f t h i s a r g u m e n t s h o u l d b e “ I S i n g l e A s s e t V a u l t ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 2 1address\_singleAssetVault, 4 9 C V F - 9 8 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c eS A S t r a t e g y C o n v e x . s o l R e c o m m e n d a t i o nT h e t y p e o f t h i s a r g u m e n t s h o u l d b e “ I R e g i s t r y ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 2 2address\_registry, C V F - 9 9 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c eS A S t r a t e g y C o n v e x . s o l R e c o m m e n d a t i o nT h e t y p e o f t h i s a r g u m e n t s h o u l d b e “ I E R C 2 0 \[ \] ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 2 4address\[\]memory\_rewardTokens C V F - 1 0 0 .I N F O •C a t e g o r yS u b o p t i m a l•S o u r c eS A S t r a t e g y C o n v e x . s o l D e s c r i p t i o nT h i s c h e c k i s r e d u n d a n t , a s i t i s a n y w a y p o s s i b l e t o p a s s a d e a d s i n g l e a s s e t v a u l t a d d r e s s . R e c o m m e n d a t i o nC o n s i d e r r e m o v i n g t h i s c h e c k . C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x . 2 9require(\_singleAssetVault!=address(0), "Invalid asset vault"); 5 0 C V F - 1 0 1 .I N F O •C a t e g o r yR e a d a b i l i t y•S o u r c eS A S t r a t e g y C o n v e x . s o l R e c o m m e n d a t i o nC o n s i d e r i n i t i a l i z i n g t o 0 f o r r e a d a b i l i t y . C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x . 4 6uint256prevLpAmounts; C V F - 1 0 2 .I N F O •C a t e g o r yS u b o p t i m a l•S o u r c eS A S t r a t e g y C o n v e x . s o l D e s c r i p t i o nT h e “ t o t a l S u p p l y ” v a l u e i s r e a d f r o m t h e s t o r a g e t w i c e ( a n d o n e a g a i n i n s i d e t h e “ \_ m i n t ” f u n c t i o n . R e c o m m e n d a t i o nC o n s i d e r r e f a c t o r i n g t h e c o d e t o r e a d i t o n l y o n c e . C l i e n t C o m m e n tW o n ’ t f i x . 5 5if(totalSupply== 0) { 5 8shares= ( newLpAmounts\* totalSupply) / prevLpAmounts; C V F - 1 0 3 .F I X E D •C a t e g o r yO v e r f l o w / U n d e r f l o w•S o u r c eS A S t r a t e g y C o n v e x . s o l D e s c r i p t i o nP h a n t o m o v e r f l o w i s p o s s i b l e h e r e . R e c o m m e n d a t i o nC o n s i d e r u s i n g a s a f e m u l D i v f u n c t i o n . 5 8shares= ( newLpAmounts\* totalSupply) / prevLpAmounts; 8 0amount+= \_withdrawLP(i, ( lpAmounts\[i\] \* shares) / totalSupply); 5 1 C V F - 1 0 5 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c eS i n g l e A s s e t V a u l t . s o l R e c o m m e n d a t i o nT h e k e y t y p e f o r t h i s m a p p i n g s h o u l d b e “ I S t r a t e g y ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 2 2mapping(address=>bool)publicisStrategy; C V F - 1 0 6 .I N F O •C a t e g o r yD o c u m e n t a t i o n•S o u r c eS i n g l e A s s e t V a u l t . s o l D e s c r i p t i o nT h e s e m a n t i c s o f t h e k e y a n d v a l u e f o r t h i s m a p p i n g i n u n c l e a r . R e c o m m e n d a t i o nC o n s i d e r d o c u m e n t i n g . C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x . 3 2mapping(address=>uint256)internalfromDepositIndex; // calculate ↪→tokenbalancefromthisdepositindex C V F - 1 0 7 .I N F O •C a t e g o r yB a d n a m i n g•S o u r c eS i n g l e A s s e t V a u l t . s o l D e s c r i p t i o nT h e n a m e i s c o n f u s i n g . R e c o m m e n d a t i o nC o n s i d e r r e n a m i n g . C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x . 3 2mapping(address=>uint256)internalfromDepositIndex; // calculate ↪→tokenbalancefromthisdepositindex 5 2 C V F - 1 0 8 .F I X E D •C a t e g o r yS u b o p t i m a l•S o u r c eS i n g l e A s s e t V a u l t . s o l D e s c r i p t i o nT h e s e m a p p i n g s a r e n o t u s e d . R e c o m m e n d a t i o nC o n s i d e r r e m o v i n g t h e m . 3 4mapping(uint256=>bool)internalvaultInvested; mapping(uint256=>bool)internalrolloverInvested; C V F - 1 0 9 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c eS i n g l e A s s e t V a u l t . s o l R e c o m m e n d a t i o nT h e t y p e o f t h e “ \_ a s s e t ” a r g u m e n t s h o u l d b e “ I E R C 2 0 ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 4 3constructor(address\_asset,address\_registry) OndoRegistryClient( ↪→\_registry) { C V F - 1 1 0 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c eS i n g l e A s s e t V a u l t . s o l R e c o m m e n d a t i o nT h e t y p e o f t h e “ \_ r e g i s t r y ” a r g u m e n t s h o u l d b e “ I R e g i s t r y ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 4 3constructor(address\_asset,address\_registry) OndoRegistryClient( ↪→\_registry) { 5 3 C V F - 1 1 1 .I N F O •C a t e g o r yS u b o p t i m a l•S o u r c eS i n g l e A s s e t V a u l t . s o l R e c o m m e n d a t i o nT h i s c h e c k i s r e d u n d a n t a s i t i s a n y w a y p o s s i b l e t o p a s s a d e a d a s s e t a d d r e s s . C l i e n t C o m m e n tW o n ’ t f i x . 4 4require(\_asset!=address(0), "Invalid asset"); C V F - 1 1 2 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c eS i n g l e A s s e t V a u l t . s o l R e c o m m e n d a t i o nT h e t y p e o f t h e “ \_ s t r a t e g y ” a r g u m e n t s h o u l d b e “ I S t r a t e g y ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 4 8functionsetStrategy(address\_strategy,bool\_flag) C V F - 1 1 3 .I N F O •C a t e g o r yD o c u m e n t a t i o n•S o u r c eS i n g l e A s s e t V a u l t . s o l D e s c r i p t i o nT h e s e m a n t i c s o f t h e “ \_ f l a g ” a r g u m e n t i s u n c l e a r f r o m i t s n a m e . R e c o m m e n d a t i o nC o n s i d e r d o c u m e n t i n g . C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x . 4 8functionsetStrategy(address\_strategy,bool\_flag) 5 4 C V F - 1 1 4 .I N F O •C a t e g o r yU n c l e a r b e h a v i o r•S o u r c eS i n g l e A s s e t V a u l t . s o l D e s c r i p t i o nT h e s e f u n c t i o n s s h o u l d e m i t s o m e e v e n t s . C l i e n t C o m m e n tW o n ’ t f i x . 4 8functionsetStrategy(address\_strategy,bool\_flag) 5 6functionsetWithdrawEnabled(bool\_withdrawEnabled) C V F - 1 1 5 .I N F O •C a t e g o r yS u b o p t i m a l•S o u r c eS i n g l e A s s e t V a u l t . s o l D e s c r i p t i o nT h i s l o g i c i s c o d e d s e v e r a l t i m e s . R e c o m m e n d a t i o nC o n s i d e r e x t r a c t i n g t o a f u n c t i o n t o r e d u c e c o d e d u p l i c a t i o n . C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x . 6 8userDeposits\[msg.sender\].push( UserDeposit({ amount: \_amount, firstActionId: actions.length}) 7 0); 8 8userDeposits\[msg.sender\].push( UserDeposit({ 9 0amount: remainAmount- \_amount, firstActionId: actions.length }) ); 1 1 1userDeposits\[msg.sender\].push( UserDeposit({ amount: remainAmount, firstActionId: actions.length ↪→}) ); 5 5 C V F - 1 1 6 .I N F O •C a t e g o r yO v e r f l o w / U n d e r f l o w•S o u r c eS i n g l e A s s e t V a u l t . s o l D e s c r i p t i o nO v e r f l o w i s p o s s i b l e h e r e t h a t w o u l d r e v e r t t h e t r a n s a c t i o n . R e c o m m e n d a t i o nC o n s i d e r u s i n g b i t w i s e “ o r ” i n s t e a d o f “ + ” . C l i e n t C o m m e n tW o n ’ t f i x 8 3require(activeInvestAmount+ passiveInvestAmount== 0, "invested!"); 1 0 7require(activeInvestAmount+ passiveInvestAmount== 0, "invested!"); C V F - 1 1 7 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c eS i n g l e A s s e t V a u l t . s o l R e c o m m e n d a t i o nT h e t y p e o f t h i s a r g u m e n t s h o u l d b e “ I S t r a t e g y ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 1 2 0address\_strategy, C V F - 1 1 8 .F I X E D •C a t e g o r yS u b o p t i m a l•S o u r c eS i n g l e A s s e t V a u l t . s o l R e c o m m e n d a t i o nT h i s c o u l d b e s i m p l i f i e d a s : i f ( \_ i s P a s s i v e ) { . . . } e l s e { . . . } 1 2 7if(\_isPassive==false) { 1 4 4}else{ 5 6 C V F - 1 1 9 .F I X E D •C a t e g o r yO v e r f l o w / U n d e r f l o w•S o u r c eS i n g l e A s s e t V a u l t . s o l D e s c r i p t i o nP h a n t o m o v e r f l o w i s p o s s i b l e h e r e i . e . a s i t u a t i o n w h e n t h e f i n a l c a l c u l a t i o n r e s u l t w o u l d f i t i n t o t h e d e s t i n a t i o n t y p e b u t s o m i n t e r m e d i a r y c a l c u l a t i o n o v e r f l o w s . R e c o m m e n d a t i o nC o n s i d e r u s i n g t h e “ m u l D i v ” f u n c t i o n a s d e s c r i b e d h e r e : h t t p s : / / x n – 2 - m b . c o m / 2 1 / m u l d i v / i n d e x . h t m l o r s o m e o t h e r a p p r o a c h , r e s i s t a n t t o p h a n t o m o v e r f l o w s . 1 3 4depositMultiplier: ( \_amount\* MULTIPLIER\_DENOMINATOR) / (totalFundAmount+ totalPassivePoolAmount), 1 8 5(redeemAmount\* MULTIPLIER\_DENOMINATOR) / pool .investAmount; 1 9 0(pool .investAmount\* MULTIPLIER\_DENOMINATOR) / (totalFundAmount+ totalPassivePoolAmount); 2 4 6(remainAmount\* pool .depositMultiplier) / MULTIPLIER\_DENOMINATOR; 2 5 2(userPoolDeposits\[action.poolId\] \* pool .redemptionMultiplier) / 2 6 2(remainAmount\* totalPassivePoolAmount) / (totalFundAmount+ totalPassivePoolAmount); C V F - 1 2 0 .I N F O •C a t e g o r yS u b o p t i m a l•S o u r c eS i n g l e A s s e t V a u l t . s o l R e c o m m e n d a t i o nT h i s l o g i c i s e x e c u t e d i n b o t h b r a n c h e s a n d s h o u l d b e p l a c e d a f t e r t h e c o n d i t i o n a l s t a t e m e n t . C l i e n t C o m m e n tC u r r e n t v e r s i o n i s m o r e r e a d a b l e , w o n ’ t f i x . 1 4 3totalActivePoolAmount+= \_amount; 1 5 6totalPassivePoolAmount+= \_amount; 5 7 C V F - 1 2 3 .F I X E D •C a t e g o r yS u b o p t i m a l•S o u r c eS i n g l e A s s e t V a u l t . s o l D e s c r i p t i o nT h e “ a c t i o n s . l e n g t h ” v a l u e i s r e a d f r o m t h e s t o r a g e o n e v e r y l o o p i t e r a t i o n . R e c o m m e n d a t i o nC o n s i d e r r e a d i n g o n c e b e f o r e t h e l o o p . 2 3 1while(depositIndex< deposits.length|| currentActionId< actions. ↪→length) { C V F - 1 2 4 .I N F O •C a t e g o r yU n c l e a r b e h a v i o r•S o u r c eS i n g l e A s s e t V a u l t . s o l D e s c r i p t i o nA c t i o n t y p e “ R e d e e m ” i s i m p l i c i t l y a s s u m e d h e r e . R e c o m m e n d a t i o nC o n s i d e r m a k i n g t h i s a s s u m p t i o n e x p l i c i t l i k e : e l s e i f ( a c t i o n . a c t i o n - T y p e = = A c t i o n T y p e . R e d e e m ) { . . . } e l s e r e v e r t ( ) ; C l i e n t C o m m e n tW o n ’ t f i x . 2 5 0}elseif(userPoolDeposits\[action.poolId\] > 0) { C V F - 1 2 5 .I N F O •C a t e g o r yD o c u m e n t a t i o n•S o u r c eS A S t r a t e g y A l l P a i r V a u l t . s o l D e s c r i p t i o nT h e s e m a n t i c s o f t h e k e y s f o r t h e s e m a p p i n g s i s u n c l e a r . R e c o m m e n d a t i o nC o n s i d e r d o c u m e n t i n g . C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x . 2 5mapping(uint256=>bool)publicvaultInvested; mapping(uint256=> InvestParam)publicinvestParams; 5 8 C V F - 1 2 6 .F I X E D •C a t e g o r yR e a d a b i l i t y•S o u r c eS A S t r a t e g y A l l P a i r V a u l t . s o l R e c o m m e n d a t i o nT h e “ v a u l t I d ” p a r a m e t e r s h o u l d b e i n d e x e d . 2 8eventInvest(uint256vaultId, OLib .Tranchetranche,uint256amount); eventRedeem(uint256vaultId, OLib .Tranchetranche,uint256amount); C V F - 1 2 7 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c eS A S t r a t e g y A l l P a i r V a u l t . s o l R e c o m m e n d a t i o nT h e t y p e o f t h i s a r g u m e n t s h o u l d b e “ I S i n g l e A s s e t V a u l t ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 3 8address\_singleAssetVault, C V F - 1 2 8 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c eS A S t r a t e g y A l l P a i r V a u l t . s o l R e c o m m e n d a t i o nT h e t y p e o f t h i s a r g u m e n t s h o u l d b e “ I P a i r V a u l t ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 3 9address\_vault, 5 9 C V F - 1 2 9 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c eS A S t r a t e g y A l l P a i r V a u l t . s o l R e c o m m e n d a t i o nT h e t y p e o f t h i s a r g u m e n t s h o u l d b e “ I R e g i s t r y ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 4 0address\_registry C V F - 1 3 0 .I N F O •C a t e g o r yS u b o p t i m a l•S o u r c eS A S t r a t e g y A l l P a i r V a u l t . s o l D e s c r i p t i o nT h e s e c h e c k s a r e r e d u n d a n t . I t i s a n y w a y p o s s i b l e t o p a s s a d e a d a d d r e s s a s a n a r g u m e n t . C l i e n t C o m m e n tW o n ’ t f i x . 4 2require(\_singleAssetVault!=address(0), "Invalid asset vault"); require(\_vault!=address(0), "Invalid AllPairVault"); C V F - 1 3 1 .F I X E D •C a t e g o r yP r o c e d u r a l•S o u r c eS A S t r a t e g y A l l P a i r V a u l t . s o l R e c o m m e n d a t i o nT h i s t r a n s f e r s h o u l d b e p o s t p o n e d u n t i l a l l t h e c h e c k s a r e m a d e . 6 2asset.safeTransferFrom(msg.sender,address(this), amount); C V F - 1 3 2 .F I X E D •C a t e g o r yP r o c e d u r a l•S o u r c eS A S t r a t e g y A l l P a i r V a u l t . s o l R e c o m m e n d a t i o nT h i s c h e c k s h o u l d b e p e r f o r m e d e a r l i e r , r i g h t a f t e r d e c o d i n g “ p a r a m s ” . 6 3require(! vaultInvested\[param.vaultId\], "vault invested"); 6 0 C V F - 1 3 4 .F I X E D •C a t e g o r yF l a w•S o u r c eS A S t r a t e g y A l l P a i r V a u l t . s o l D e s c r i p t i o nT h e s t a t e i s u p d a t e d a f t e r c a l l i n g e x t e r n a l c o n t r a c t s , w h i c h c o u l d m a k e a r e e n t r a n c y a t t a c k p o s s i b l e . R e c o m m e n d a t i o nC o n s i d e r r e f a c t o r i n g t h e c o d e t o d o s t a t e u p d a t e s b e f o r e c a l l i n g e x - t e r n a l c o n t r a c t s . 9 6vaultInvested\[investParam.vaultId\] =false; C V F - 1 3 5 .F I X E D •C a t e g o r yF l a w•S o u r c eS A S t r a t e g y A l l P a i r V a u l t . s o l D e s c r i p t i o nT h e “ w i t h d r a w ” f u n c t i o n r e t u r n s t h e w i t h d r a w n a m o u n t . R e c o m m e n d a t i o nC o n s i d e r u s i n g a r e t u r n e d v a l u e i n s t e a d o f a c a l c u l a t e d o n e . 1 0 3// calculatewithdrawnbalance amount= asset.balanceOf(address(this)) -amount; C V F - 1 3 6 .F I X E D •C a t e g o r yS u b o p t i m a l•S o u r c eS A S t r a t e g y A l l P a i r V a u l t . s o l R e c o m m e n d a t i o nC o n s i d e r d o i n g t h i s o n l y w h e n a m o u n t > 0 . 1 0 6asset.safeTransfer(msg.sender, amount); emitRedeem(investParam.vaultId, investParam.tranche, amount); C V F - 1 3 7 .F I X E D •C a t e g o r yP r o c e d u r a l•S o u r c eO n d o L i b r a r y . s o l R e c o m m e n d a t i o nT h i s c o m m e n t e d o u t i m p o r t s h o u l d b e r e m o v e d . 8// import"@openzeppelin/contracts/utils/Address.sol "; 6 1 C V F - 1 3 8 .I N F O •C a t e g o r yP r o c e d u r a l•S o u r c eO n d o L i b r a r y . s o l D e s c r i p t i o nT h el i b r a r yn a m e( “ O L i b ” ) i si n c o n s i s t e n t w i t ht h ef i l en a m e( “ O n - d o L i b r a r y . s o l ” ) . T h i s m a k e s i t h a r d e r t o n a v i g a t e t h r o u g h t h e c o d e . R e c o m m e n d a t i o nC o n s i d e r n a m i n g c o n s i s t e n t l y . C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x . 1 3libraryOLib{ C V F - 1 3 9 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c eO n d o L i b r a r y . s o l R e c o m m e n d a t i o nT h e t y p e o f t h e s e f i e l d s s h o u l d b e “ I E R C 2 0 ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 2 3addressseniorAsset; addressjuniorAsset; C V F - 1 4 0 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c eO n d o L i b r a r y . s o l R e c o m m e n d a t i o nT h e t y p e o f t h i s f i e l d s h o u l d b e “ I S t r a t e g y ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 2 6addressstrategy; 6 2 C V F - 1 4 1 .I N F O •C a t e g o r yD o c u m e n t a t i o n•S o u r c eO n d o L i b r a r y . s o l D e s c r i p t i o nT h e n u m b e r f o r m a t o f t h i s f i e l d i s u n c l e a r . R e c o m m e n d a t i o nC o n s i d e r d o c u m e n t i n g . C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x . 2 7uint256hurdleRate; C V F - 1 4 2 .I N F O •C a t e g o r yS u b o p t i m a l•S o u r c eO n d o L i b r a r y . s o l D e s c r i p t i o nT h e s e t w o a r r a y s s e e m t o a l w a y s h a v e t h e s a m e l e n g t h . U s i n g a s i n g l e a r r a y o f s t r u c t s w i t h t w o f i e l d s w o u l d b e m o r e e f f i c i e n t a s t h e l e n g t h w i l l o n l y b e s t o r e d o n c e . C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x . 6 8uint256\[\] userSums; uint256\[\] prefixSums; C V F - 1 4 3 .I N F O •C a t e g o r yD o c u m e n t a t i o n•S o u r c eO n d o L i b r a r y . s o l D e s c r i p t i o nT h e s e m a n t i c s o f t h e r e t u r n e d v a l u e s i s u n c l e a r . R e c o m m e n d a t i o nC o n s i d e r d o c u m e n t i n g . C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x . 9 4returns(uint256userInvested,uint256excess) 6 3 C V F - 1 4 4 .I N F O •C a t e g o r yS u b o p t i m a l•S o u r c eO n d o L i b r a r y . s o l R e c o m m e n d a t i o nI t w o u l d b e c l e a r t o s a y : r e t u r n ( 0 , 0 ) ; C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x . 1 0 0return(userInvested, excess); C V F - 1 4 5 .I N F O •C a t e g o r yS u b o p t i m a l•S o u r c eO n d o L i b r a r y . s o l R e c o m m e n d a t i o nI t w o u l d b e c l e a r e r t o s a y : r e t u r n ( i n v e s t o r . u s e r S u m s \[ l e n g t h - 1 \] , 0 ) ; C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x . 1 0 5userInvested= investor.userSums\[length- 1\]; return(userInvested, excess); C V F - 1 4 6 .I N F O •C a t e g o r yS u b o p t i m a l•S o u r c eO n d o L i b r a r y . s o l D e s c r i p t i o nI n a l l t h e s e c a s e s , “ e x c e s s ” a c t u a l l y e q u a l s t o “ i n v e s t o r . u s e r S u m s \[ l e n g t h - 1 \] - u s e r I n v e s t e d ” . R e c o m m e n d a t i o nC o n s i d e r c a l c u l a t i n g e x c e s s i n o n e p l a c e a f t e r a l l t h e c o n d i t i o n a l o p - e r a t o r s . C l i e n t C o m m e n tN e g l i g i b l e s a v i n g s , w o n ’ t f i x . 1 0 6return(userInvested, excess); 1 1 2excess= investor.userSums\[length- 1\] -userInvested; 1 2 3excess= investor.userSums\[length- 1\] -userInvested; 1 2 5excess= investor.userSums\[length- 1\] -userInvested; 6 4 C V F - 1 4 7 .I N F O •C a t e g o r yS u b o p t i m a l•S o u r c eO n d o L i b r a r y . s o l D e s c r i p t i o nT h e e x p r e s s i o n “ p r e f i x S u m - d e p o s i t A m o u n t ” i s i m p l i c i t l y c a l c u l a t e d t w i c e . R e c o m m e n d a t i o nC o n s i d e r r e f a c t o r i n g l i k e t h i s t o c a l c u l a t e i t o n l y o n c e : u i n t 2 5 6 p r e f i x - S u m B e f o r e D e p o s i t = p r e f i x S u m - d e p o s i t A m o u n t ; i f ( p r e f i x S u m B e f o r e D e p o s i t < i n v e s t e d ) { u s e r I n v e s t e d + = i n v e s t e d - p r e f i x S u m B e f o r e D e p o s i t ; C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x . 1 2 1if(prefixSum- depositAmount< invested) { userInvested+= ( depositAmount+ invested- prefixSum); C V F - 1 4 8 .I N F O •C a t e g o r yP r o c e d u r a l•S o u r c eO n d o L i b r a r y . s o l R e c o m m e n d a t i o nT h i s l i b r a r y s h o u l d b e m o v e d t o a f i l e n a m e d “ O n d o S a f e r E R C 2 0 ” . C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x . 1 4 0libraryOndoSaferERC20{ C V F - 1 5 0 .I N F O •C a t e g o r yS u b o p t i m a l•S o u r c eO n d o L i b r a r y . s o l D e s c r i p t i o nT h i s n e e d t o b e e x e c u t e d o n l y i n c a s e t h e c u r r e n t a l l o w a n c e ( o b t a i n e d i n t h e p r e v i o u s l i n e ) i s n o t z e r o . C l i e n t C o m m e n tW o n ’ t f i x . 1 4 9token.safeApprove(spender, 0); 6 5 C V F - 1 5 1 .I N F O •C a t e g o r yP r o c e d u r a l•S o u r c eI C u r v e \_ 3 . s o l D e s c r i p t i o nI nt h ec u r v ec o d e ,t h i sf u n c t i o ni sd e c l a r e da s“ p a y a b l e ” ,w h i c h m e a n st h a ti tc o u l da c c e p te t h e r ,b u tt h i sf u n c t i o ni sd e c l a r e dw i t h o u tt h e “ p a y a b l e ” m o d i f i e r , s oi t c a n n o t a c c e p t e t h e r :h t t p s : / / g i t h u b . c o m / c u r v e f i / d e p o s i t - n d - s t a k e - z a p / b l o b / 2 1 8 3 c f a 0 3 d 2 3 b 9 a 1 e 5 7 2 d 4 6 3 3 2 d 7 3 a d 3 0 b 3 9 8 4 5 d / c o n t r a c t s / d e - p o s i t \_ a n d \_ s t a k e \_ z a p . v y # L 2 1 P r o b a b l y n o t a n i s s u e . C l i e n t C o m m e n tK e e p i n g f u n c t i o n a l y a s - i s , w o n ’ t f i x . 5functionadd\_liquidity(uint256\[3\] calldataamounts,uint256 ↪→min\_mint\_amount) external; C V F - 1 5 2 .I N F O •C a t e g o r yU n c l e a r b e h a v i o r•S o u r c eI C u r v e \_ 3 . s o l D e s c r i p t i o nI t i s u n c l e a r w h i c h C u r v e f u n c t i o n s t h e s e f u n c t i o n s c o r r e s p o n d s t o . R e c o m m e n d a t i o nC o n s i d e r p r o v i d i n g r e f e r e n c e s . C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x . 8functionremove\_liquidity\_one\_coin( uint256burn\_amount, 1 0int128i, uint256mim\_received )external; 1 4functioncoins(uint256)externalviewreturns(address); 6 6 C V F - 1 5 3 .I N F O •C a t e g o r yD o c u m e n t a t i o n•S o u r c eI C u r v e \_ 3 . s o l D e s c r i p t i o nT h e s e m a n t i c s o f t h e r e t u r n e d v a l u e i s u n c l e a r . R e c o m m e n d a t i o nC o n s i d e r d o c u m e n t i n g . C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x . 1 4functioncoins(uint256)externalviewreturns(address); C V F - 1 5 4 .I N F O •C a t e g o r yD o c u m e n t a t i o n•S o u r c eI B a s e R e w a r d P o o l . s o l D e s c r i p t i o nT h e s e m a n t i c s o f t h e a r g u m e n t s a r e t h e r e t u r n e d v a l u e s i s u n c l e a r . R e c o m m e n d a t i o nC o n s i d e r g i v i n g t h e m d e s c r i p t i v e n a m e s a n d / o r a d d i n g d o c u m e n t a t i o n c o m m e n t s . C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x . 5functiongetReward()externalreturns(bool); 7functionbalanceOf(address)externalviewreturns(uint256); 9functionwithdrawAndUnwrap(uint256,bool)externalreturns(bool); 6 7 C V F - 1 5 5 .I N F O •C a t e g o r yD o c u m e n t a t i o n•S o u r c eI C o n v e x B o o s t e r . s o l D e s c r i p t i o nT h e s e m a n t i c s o f t h e a r g u m e n t s a n d r e t u r n e d v a l u e s i s u n c l e a r . R e c o m m e n d a t i o nC o n s i d e r g i v i n g t h e m d e s c r i p t i v e n a m e s a n d / o r a d d i n g d o c u m e n t a t i o n c o m m e n t s . C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x . 5functiondeposit( uint256, uint256, bool )externalreturns(bool); 1 1functionwithdraw(uint256,uint256)externalreturns(bool); C V F - 1 5 6 .I N F O •C a t e g o r yD o c u m e n t a t i o n•S o u r c eI C o n v e x B o o s t e r . s o l D e s c r i p t i o nI t i s u n c l e a r w h a t C o n v e x f u n c t i o n s t h e s e f u n c t i o n c o r r e s p o n d t o . R e c o m m e n d a t i o nC o n s i d e r d o c u m e n t i n g o r u s i n g C o n v e x i n t e r f a c e s d i r e c t l y f r o m C o n - v e x r e p o s i t o r y . C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x . 5functiondeposit( 1 1functionwithdraw(uint256,uint256)externalreturns(bool); 6 8 C V F - 1 5 7 .F I X E D •C a t e g o r yP r o c e d u r a l•S o u r c eI C u r v e \_ 2 . s o l D e s c r i p t i o nI n t h e c u r v e c o d e , t h i s f u n c t i o n i s d e c l a r e d a s “ p a y a b l e ” , w h i c h m e a n s t h a t i t c o u l da c c e p t e t h e r ,b u t h i sf u n c t i o ni sd e c l a r e dw i t h o u t t h e“ p a y a b l e ” m o d i f i e r ,s oi tc a n n o ta c c e p te t h e r :h t t p s : / / g i t h u b . c o m / c u r v e f i / d e p o s i t - a n d - t a k e - z a p / b l o b / 2 1 8 3 c f a 0 3 d 2 3 b 9 a 1 e 5 7 2 d 4 6 3 3 2 d 7 3 a d 3 0 b 3 9 8 4 5 d / c o n t r a c t s / d e - p o s i t \_ a n d \_ s t a k e \_ z a p . v y # L 1 8 P r o b a b l y n o t a n i s s u e . 5functionadd\_liquidity(uint256\[2\] calldataamounts,uint256 ↪→min\_mint\_amount) external; C V F - 1 5 8 .I N F O •C a t e g o r yU n c l e a r b e h a v i o r•S o u r c eI C u r v e \_ 2 . s o l D e s c r i p t i o nI t i s u n c l e a r w h i c h C u r v e f u n c t i o n s t h e s e f u n c t i o n s c o r r e s p o n d s t o . R e c o m m e n d a t i o nC o n s i d e r p r o v i d i n g r e f e r e n c e s . C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x . 8functionremove\_liquidity\_one\_coin( uint256burn\_amount, 1 0int128i, uint256mim\_received )externalreturns(uint256); 1 4functioncoins(uint256)externalviewreturns(address); 6 9 C V F - 1 5 9 .I N F O •C a t e g o r yD o c u m e n t a t i o n•S o u r c eI C u r v e \_ 2 . s o l D e s c r i p t i o nT h e s e m a n t i c s o f t h e r e t u r n e d v a l u e i s u n c l e a r . R e c o m m e n d a t i o nC o n s i d e r d o c u m e n t i n g . C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x . 1 2)externalreturns(uint256); 1 4functioncoins(uint256)externalviewreturns(address); C V F - 1 6 0 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c eI S i n g l e A s s e t V a u l t . s o l R e c o m m e n d a t i o nT h e t y p e o f t h i s f i e l d s h o u l d b e “ I S t r a t e g y ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 4 3addressstrategy; C V F - 1 6 1 .F I X E D •C a t e g o r yS u b o p t i m a l•S o u r c eI S A S t r a t e g y . s o l D e s c r i p t i o nT h e s e f u n c t i o n s s h o u l d e m i t s o m e e v e n t s a n d t h e s e e v e n t s s h o u l d b e d e - c l a r e d i n t h i s i n t e r f a c e . 5functioninvest( 1 1functionredeem(uint256poolId,bytesmemorydata) 7 0 C V F - 1 6 2 .I N F O •C a t e g o r yD o c u m e n t a t i o n•S o u r c eI S A S t r a t e g y . s o l D e s c r i p t i o nT h e s e m a n t i c s o f t h e r e t u r n e d v a l u e s i s u n c l e a r . R e c o m m e n d a t i o nC o n s i d e r g i v i n g t h e m d e s c r i p t i v e n a m e s a n d / o r a d d i n g a d o c u m e n t a - t i o n c o m m e n t . C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x . 1 3returns(bool,uint256); C V F - 1 6 3 .F I X E D •C a t e g o r yP r o c e d u r a l•S o u r c eI R o l l o v e r . s o l D e s c r i p t i o nT h i s f i l e i s i m p o r t e d t w i c e . R e c o m m e n d a t i o nR e m o v e o n e i m p o r t . 6import"contracts/interfaces/ITrancheToken.sol"; 8import"contracts/interfaces/ITrancheToken.sol"; 7 1 C V F - 1 6 4 .I N F O •C a t e g o r yB a d n a m i n g•S o u r c eI R o l l o v e r . s o l R e c o m m e n d a t i o nE v e n t s a r e u s u a l l y n a m e d v i a n o u n s , s u c h a s “ R o l l o v e r ” , “ V a u l t ” , “ M i - g r a t i o n ” , e t c . C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x . 1 3eventCreatedRollover( 2 3eventAddedVault(uint256indexedrolloverId,uint256indexedvaultId ↪→); 2 5eventMigratedRollover( 3 2eventWithdrew( 4 0eventDeposited( 4 9eventClaimed( C V F - 1 6 5 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c eI R o l l o v e r . s o l R e c o m m e n d a t i o nT h e t y p e o f t h e s e p a r a m e t e r s s h o u l d b e “ I E R C 2 0 ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 1 7addressseniorAsset, addressjuniorAsset, addressseniorToken, 2 0addressjuniorToken 7 2 C V F - 1 6 6 .I N F O •C a t e g o r yS u b o p t i m a l•S o u r c eI R o l l o v e r . s o l D e s c r i p t i o nI t s e e m s t h a t t h e l e n g t h o f t h e s e a r r a y s i s a l w a y s 2 . R e c o m m e n d a t i o nC o n s i d e r d e c l a r i n g a s “ I E R C 2 0 \[ 2 \] ” a n d “ I T r a n c h e T o k e n \[ 2 \] ” . C l i e n t C o m m e n tW o n ’ t f i x . 7 6IERC20\[\] assets; ITrancheToken\[\] rolloverTokens; C V F - 1 6 7 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c eI R o l l o v e r . s o l R e c o m m e n d a t i o nT h e s e f i e l d c o u l d b e r e p l a c e d w i t h a s i n g l e f i e l d o f t y p e “ T r a n c h e R - o u n d V i e w ” . C l i e n t C o m m e n tW o n ’ t f i x . 8 2uint256deposited; uint256invested; // Total, if any , actuallyinvested uint256redeemed; // AfterVaultis done , totaltokensredeemedfor ↪→LP uint256shares; uint256newDeposited; uint256newInvested; C V F - 1 6 8 .I N F O •C a t e g o r yB a d n a m i n g•S o u r c eI W E T H . s o l D e s c r i p t i o nT h e a r g u m e n t n a m e “ w a d ” i s m i s l e a d i n g .T h i s a r g u m e n t i s a c t u a l l y t h e a m o u n t t o b e w i t h d r a w n . C l i e n t C o m m e n tW o n ’ t f i x . 9functionwithdraw(uint256wad )external; 7 3 C V F - 1 6 9 .F I X E D •C a t e g o r yS u b o p t i m a l•S o u r c eI R e g i s t r y . s o l D e s c r i p t i o nT h e s e f u n c t i o n s s h o u l d e m i t s o m e e v e n t s a n d t h e s e e v e n t s s h o u l d b e d e - c l a r e d i n t h i s i n t e r f a c e . 1 4functionpause()external; 1 6functionunpause()external; 1 8functionenableFeatureFlag(bytes32\_featureFlag)external; 2 0functiondisableFeatureFlag(bytes32\_featureFlag)external; 2 4functiondeleteFeatureFlag(bytes32\_featureFlag)external; C V F - 1 7 0 .F I X E D •C a t e g o r yD o c u m e n t a t i o n•S o u r c eI R e g i s t r y . s o l D e s c r i p t i o nI t i s u n c l e a r h o w t h e s e t w o f u n c t i o n d o d i f f e r . R e c o m m e n d a t i o nC o n s i d e r d o c u m e n t i n g . 2 0functiondisableFeatureFlag(bytes32\_featureFlag)external; 2 4functiondeleteFeatureFlag(bytes32\_featureFlag)external; 7 4 C V F - 1 7 1 .I N F O •C a t e g o r yS u b o p t i m a l•S o u r c eI R e g i s t r y . s o l D e s c r i p t i o nT h i s f u n c t i o n i s a n a l i a s f o r t h e “ h a s R o l e ” f u n c t i o n d e c l a r e d i n t h e “ I A c c e s s - C o n t r o l ” i n t e r f a c e . R e c o m m e n d a t i o nC o n s i d e r r e m o v i n g t h i s f u n c t i o n a n d u s i n g “ h a s R o l e ” i n s t e a d . C l i e n t C o m m e n tN o d i f f e r e n c e , w o n ’ t f i x . 3 0functionauthorized(bytes32\_role,address\_account) external view returns(bool); C V F - 1 7 2 .I N F O •C a t e g o r yB a d n a m i n g•S o u r c eI S t r a t e g y . s o l D e s c r i p t i o nD e s p i t e t h e n a m e , t h i s f u n c t i o n r e t u r n s i n f o r m a t i o n a b o u t a s i n g l e v a u l t . R e c o m m e n d a t i o nC o n s i d e r r e n a m i n g t o “ v a u l t ” o r “ g e t V a u l t ” . C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x . 2 0functionvaults(uint256vaultId) 7 5 C V F - 1 7 3 .I N F O •C a t e g o r yS u b o p t i m a l•S o u r c eI S t r a t e g y . s o l D e s c r i p t i o nT h i s f u n c t i o n s h o u l d r e t u r n a n i n s t a n c e o f t h e “ V a u l t ” s t r u c t u r e . C l i e n t C o m m e n tO v e r r i d e n b y v a u l t s t r u c t , w o n ’ t f i x . 2 3returns( IPairVaultorigin, IERC20pool , IERC20senior, IERC20junior, uint256shares, uint256seniorExcess, 3 0uint256juniorExcess ); C V F - 1 7 4 .F I X E D •C a t e g o r yD o c u m e n t a t i o n•S o u r c eI S t r a t e g y . s o l D e s c r i p t i o nT h e s e m a n t i c s o f t h i s f u n c t i o n i s u n c l e a r . R e c o m m e n d a t i o nC o n s i d e r d o c u m e n t i n g . 3 9functionaddLp(uint256\_vaultId,uint256\_lpTokens)external; 4 1functionremoveLp( 8 3functionwithdrawExcess( 7 6 C V F - 1 7 5 .F I X E D •C a t e g o r yP r o c e d u r a l•S o u r c eI S t r a t e g y . s o l D e s c r i p t i o nA n L P a m o u n t a r g u m e n t i s n a m e d “ \_ l p T l o k e n s ” i n t h e f o r m e r c a s e a n d “ \_ s h a r e d ” i n t h e l a t t e r c a s e . R e c o m m e n d a t i o nC o n s i d e r u s i n g c o n s i s t e n t n a m i n g . 3 9functionaddLp(uint256\_vaultId,uint256\_lpTokens)external; 4 3uint256\_shares, C V F - 1 7 6 .F I X E D •C a t e g o r yD o c u m e n t a t i o n•S o u r c eI S t r a t e g y . s o l D e s c r i p t i o nT h e s e m a n t i c s o f t h e r e t u r n e d v a l u e s i s u n c l e a r . R e c o m m e n d a t i o nC o n s i d e r d o c u m e n t i n g . 5 0returns(IERC20,uint256); 8 1)externalreturns(uint256,uint256); 7 7 C V F - 1 7 7 .F I X E D •C a t e g o r yD o c u m e n t a t i o n•S o u r c eI S t r a t e g y . s o l D e s c r i p t i o nT h e s e m a n t i c s o f t h e s e a m o u n t s i s u n c l e a r . R e c o m m e n d a t i o nC o n s i d e r d o c u m e n t i n g . 5 4uint256\_totalSenior, uint256\_totalJunior, uint256\_extraSenior, uint256\_extraJunior, uint256\_seniorMinOut, uint256\_juniorMinOut 7 8uint256\_seniorExpected, uint256\_seniorMinOut, 8 0uint256\_juniorMinOut C V F - 1 7 8 .F I X E D •C a t e g o r yD o c u m e n t a t i o n•S o u r c eI S t r a t e g y . s o l D e s c r i p t i o nT h e s e m a n t i c s o f t h i s f u n c t i o n a n d i t s r e t u r n v a l u e s i s u n c l e a r . R e c o m m e n d a t i o nC o n s i d e r d o c u m e n t i n g . 6 2functionsharesFromLp(uint256vaultId,uint256lpTokens) external view returns( uint256shares, uint256vaultShares, IERC20pool ); 7 1functionlpFromShares(uint256vaultId,uint256shares) external view returns(uint256lpTokens,uint256vaultShares); 7 8 C V F - 1 7 9 .F I X E D •C a t e g o r yD o c u m e n t a t i o n•S o u r c eI P a i r V a u l t . s o l D e s c r i p t i o nT h e s e m a n t i c s o f t h i s f i e l d i s u n c l e a r a n d i s n o t d o c u m e n t e d . R e c o m m e n d a t i o nC o n s i d e r a d d i n g a c o m m e n t . 1 6addressrollover; C V F - 1 8 0 .F I X E D •C a t e g o r yD o c u m e n t a t i o n•S o u r c eI P a i r V a u l t . s o l D e s c r i p t i o nT h e n u m b e r f o r m a t o f t h i s f i e l d i s u n c l e a r . R e c o m m e n d a t i o nC o n s i d e r d o c u m e n t i n g . 1 7uint256hurdleRate; // Returnofferedto seniortranche C V F - 1 8 1 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c eI P a i r V a u l t . s o l R e c o m m e n d a t i o nT h e t y p e o f t h i s f i e l d s h o u l d p r o b a b l y b e “ I R o l l o v e r ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 1 6addressrollover; 7 9 C V F - 1 8 2 .F I X E D •C a t e g o r yD o c u m e n t a t i o n•S o u r c eI P a i r V a u l t . s o l D e s c r i p t i o nT h e s e m a n t i c s o f t h e s e a m o u n t s i s u n c l e a r . R e c o m m e n d a t i o nC o n s i d e r d o c u m e n t i n g . 3 1uint256originalInvested; uint256totalInvested; // not literal1:1,originalInvested+ ↪→proportionallp frommid -term uint256received; uint256rolloverDeposited; C V F - 1 8 3 .F I X E D •C a t e g o r yD o c u m e n t a t i o n•S o u r c eI P a i r V a u l t . s o l D e s c r i p t i o nT h i s c o m m e n t i s c o n f u s i n g . R e c o m m e n d a t i o nC o n s i d e r a d d i n g m o r e d e t a i l s . 3 2uint256totalInvested; // not literal1:1,originalInvested+ ↪→proportionallp frommid -term C V F - 1 8 4 .F I X E D •C a t e g o r yD o c u m e n t a t i o n•S o u r c eI P a i r V a u l t . s o l D e s c r i p t i o nT h e d i f f e r e n c e b e t w e e n d e p o s i t i n g a n d i n v e s t i n g i s u n c l e a r . R e c o m m e n d a t i o nC o n s i d e r d o c u m e n t i n g . 4 3functiondeposit( 4 9functiondepositETH(uint256\_vaultId, OLib .Tranche\_tranche) ↪→externalpayable; 5 1functiondepositLp(uint256\_vaultId,uint256\_amount) 5 5functioninvest( 8 0 C V F - 1 8 5 .F I X E D •C a t e g o r yD o c u m e n t a t i o n•S o u r c eI P a i r V a u l t . s o l D e s c r i p t i o nT h e s e m a n t i c s o f t h e r e t u r n e d v a l u e s i s u n c l e a r . R e c o m m e n d a t i o nC o n s i d e r d o c u m e n t i n g . 5 9)externalreturns(uint256,uint256); 6 5)externalreturns(uint256,uint256); 6 9returns(uint256); 7 3returns(uint256); 7 7returns(uint256,uint256); 8 1returns(uint256,uint256); 8 5returns(uint256,uint256); 9 6returns(uint256,uint256); 8 1 C V F - 1 8 6 .F I X E D •C a t e g o r yD o c u m e n t a t i o n•S o u r c eI P a i r V a u l t . s o l D e s c r i p t i o nT h e d i f f e r e n c e b e t w e e n r e d e e m i n g , w i t h d r a w i n g , a n d c l a i m i n g i s u n c l e a r . R e c o m m e n d a t i o nC o n s i d e r d o c u m e n t i n g . 6 1functionredeem( 6 7functionwithdraw(uint256\_vaultId, OLib .Tranche\_tranche) 7 1functionwithdrawETH(uint256\_vaultId, OLib .Tranche\_tranche) 7 5functionwithdrawLp(uint256\_vaultId,uint256\_amount) 7 9functionclaim(uint256\_vaultId, OLib .Tranche\_tranche) 8 3functionclaimETH(uint256\_vaultId, OLib .Tranche\_tranche) C V F - 1 8 7 .F I X E D •C a t e g o r yD o c u m e n t a t i o n•S o u r c eI P a i r V a u l t . s o l D e s c r i p t i o nT h e s e m a n t i c s o f t h e s e f u n c t i o n s i s u n c l e a r . R e c o m m e n d a t i o nC o n s i d e r d o c u m e n t i n g . 8 7functiondepositFromRollover( 9 4functionrolloverClaim(uint256\_vaultId,uint256\_rolloverId) 1 1 6functionvaultInvestor(uint256\_vaultId, OLib .Tranche\_tranche) 1 2 6functionseniorExpected(uint256\_vaultId)externalviewreturns( ↪→uint256); 8 2 C V F - 1 8 8 .I N F O •C a t e g o r yB a d d a t a t y p e•S o u r c eI P a i r V a u l t . s o l R e c o m m e n d a t i o nT h e t y p e o f t h i s a r g u m e n t s h o u l d p r o b a b l y b e “ I R o l l o v e r ” . C l i e n t C o m m e n tW e h a v e a d o p t e d i n o u r t e a m ’s s o l i d i t y s t y l e g u i d e t o g e n e r a l l y p r e f e r t h e m o r e g e n e r i c ‘ a d d r e s s ‘ d a t a t y p e . 1 0 0address\_rollover, C V F - 1 8 9 .F I X E D •C a t e g o r yP r o c e d u r a l•S o u r c eI P a i r V a u l t . s o l R e c o m m e n d a t i o nT h i s c o m m e n t e d o u t f u n c t i o n s h o u l d b e r e m o v e d . 1 0 6// functioncanTransition(uint256\_vaultId, OLib .State\_state) //external //view //returns(bool ); C V F - 1 9 0 .F I X E D •C a t e g o r yD o c u m e n t a t i o n•S o u r c eI T r a n c h e T o k e n . s o l D e s c r i p t i o nT h e s e m a n t i c s o f t h i s f u n c t i o n i s u n c l e a r . R e c o m m e n d a t i o nC o n s i d e r d o c u m e n t i n g . C l i e n t C o m m e n tF u n c t i o n r e m o v e d . 1 1functiondestroy(addresspayable\_receiver)external; 8 3 C V F - 1 9 1 .I N F O •C a t e g o r yP r o c e d u r a l•S o u r c eI M u l t i e x . s o l R e c o m m e n d a t i o nC o n s i d e r n a m i n g t h e f u n c t i o n i n c a m e l C a s e , i . e . “ m u l t i e x C a l l ” . C l i e n t C o m m e n tS t y l e g u i d e c o n f l i c t , w o n ’ t f i x . 1 0functionmultiexcall(Call\[\] calldatacalls) 8 4 d m i t r y @ a b d k c o n s u l t i n g . c o m t w i t t e r . c o m / A B D K c o n s u l t i n g a b d k . c o n s u l t i n g l i n k e d i n . c o m / c o m p a n y / a b d k - c o n s u l t i n g
---
# 404: This page could not be found
404
===
This page could not be found.
-----------------------------
---
# 404: This page could not be found
404
===
This page could not be found.
-----------------------------
---