As of 21 Oct 2026, Open Dollar has 3 audit reports by 2 security firms on Trustblock; the latest is by Quantstamp, dated 23 Apr 2024. Those reports list no open critical findings.
Record last updated . It holds audits and findings, contracts and incidents up to Oct 2026. Trustblock does not review code.
Newest first
| Audit | Security firm | Date | Scope | Critical findings | Report |
|---|---|---|---|---|---|
| Open Dollar - Smart Contract Audit | Security firm: Quantstamp | Date: | Scope: Repository at commit 6fbe167 | No open critical findings | Open · certificate.quantstamp.com |
| OpenDollar security review | Security firm: Pashov Audit Group | Date: | Scope: Not recorded (see the report) | No open critical findings | Open · GitHub |
| Open Dollar - dApp | Security firm: Quantstamp | Date: | Scope: Repository at commit 07ba83f | No open critical findings | Open · certificate.quantstamp.com |
Statuses are the security firm’s own, from each report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 0 |
| High | 0 | 0 | 0 |
| Medium | 0 | 2 | 4 |
| Low | 1 | 12 | 14 |
The Open Dollar Protocol introduces the ability of Safe ownership via an NFT. This is done via a `Vault721` contract that acts as the minter of the NFTs and an `ODSafeManager` that is the entry point to manage all the NFV (Non-Fungible Vault) positions. However, by calling `SafeEngine.modifySAFECollateralization()` directly, a user can open a position that does not map to an NFV. Users also have the ability to bypass the `ITaxCollector(taxCollector).taxSingle`, as this call is done in `ODSafeManager` and not in `SAFEEngine` directly. This would allow the user to directly manage the Vault position without interacting with the tax collector and hence take on debt without having to fund the surplus fund, which would be used to cover bad debt.
Open the reportThe `ChainlinkRelayer.latestRoundData()` function fetches the latest price of an asset from Chainlink price feeds. However, as the protocol is intended to be deployed on Arbitrum, checking the sequencer's uptime before querying price data is crucial. If the sequencer is down, there is a chance of using an incorrect or stale price. Please refer to the [Chainlink L2 Sequencer Uptime Feeds](https://docs.chain.link/data-feeds/l2-sequencer-feeds) document for more details.
Open the reportA user can assign an `ISAFESaviour` to their NFV. If a liquidation attempt is ever made, the `LiquidationEngine` will first make a call to `ISAFESaviour.saveSAFE()` to give the savior an opportunity to restore the safe to a healthy collateralization ratio before it is liquidated. The current implementation maintains the assigned savior after an `NFV` transfer. Whilst the savior implementations may vary, the `LiquidationEngine.protectSAFE()` call assigns a savior to a particular safe rather than the safe owner. A user may want to maintain their savior to protect their NFV until a sale is guaranteed, but there is no clear way to facilitate the removal of a savior before an NFV transfer. Though this behavior is documented, we would like to note that this behavior is restrictive for listed NFV's.
Open the reportThe report gives no description here.
Open the reportOne of the protections introduced for issue OD-1 is the `blockdelay` for addresses on the `_allowlist`. It adds an extra check that the last `_hashState[_tokenId].lastBlockNumber` is at least `blockdelay` blocks old compared to the current `block.number`. This is a good idea, but `blockDelay` is a `uint8`, which can maximum be 256 blocks, which may be insufficient for validating NFV purchases.
Open the reportTo help marketplaces accurately list NFVs and protect users from trading NFV's whose prices have recently changed, the `NFTRenderer` calculates a `stateHash` that reflects the value of each vault. `Vault721` validates that a sufficient number of blocks have passed for a given `stateHash` before facilitating a transfer, giving users to time to be accurately informed about the value of a safe. However, the current `stateHash` only includes a vault's `SAFE.lockedCollateral` and `SAFE.generatedDebt`. This does not capture the additional value held in a vault's `SafeEngine.coinBalance` and `SafeEngine.tokenCollateral`. Additionally, a vault's `stateHash` is not updated when `ODSafeManager.transferInternalCoins()` is called. If a vault transfers its internal coins to another address, its value would drop, and thus the transfer should enforce the time delay.
Open the reportThe `handlerCan[]` mapping in `ODSafeManager` tracks permissions for performing operations on a specific `SafeHandler`. It is used in the `quitSystem()` and `enterSystem()` functions. However, there is no way for a `SafeHandler` to call `ODSafeManager.allowHandler()`, making the functions uncallable.
Open the report`DebtAuctionHouse` facilitates auctions to pay off bad debt. Users bid to pay off debt in exchange for governance tokens. If an auction expires without any users placing a bid, the auction can be restarted by calling `restartAuction()` with a more favorable payout of governance tokens. However, it is unclear who would be responsible for restarting the auction. A user who calls `restartAuction()`, places a bid, and then is later outbid will have fronted the gas costs for restarting the auction. This may disincentivize users from restarting auctions, in hopes that a different user might pay the gas costs.
Open the reportIt is important to validate inputs, even if they only come from trusted addresses, to avoid human error. Specifically, in the following functions: * `AccountingEngine.constructor()`: Validate that `_debtAuctionHouse` is a non-zero address. * `AccountingEngine._validateParameters()`: Validate that `debtAuctionMintedTokens` is non-zero. * `Authorizable._addAuthorization()`: Validate that `_account` is a non-zero address. * `CollateralAuctionHouse._validateParameters()`: Validate that `minimumBid` is non-zero. * `DebtAuctionHouse._validateParameters()`: Validate that `bidDecrease` and `amountSoldIncrease` are non-zero. * `SurplusAuctionHouse._validateParameters()`: * Validate that `bidIncrease`, `bidDuration`, and `totalAuctionLength` are non-zero. * Validate that `totalAuctionLength` is greater than `bidDuration`. * Validate that `recyclingPercentage` is less than 100%. * `Vault721.updateVaultHashState()` doesn't check if SAFE exists. * `initializeManager()` and `initializeRenderer()`should have access controls.
Open the report`Vault721._afterTokenTransfer()` checks whether the NFV recipient has an `ODProxy` contract deployed. If no `ODProxy` is linked to their address, it will deploy and link a new `ODProxy` to the recipient. However, this assumes that the `_from` address will be an EOA. If the `_from` address is an `ODProxy`, a new `ODProxy` will be deployed and the original `ODProxy` will be added to the `_userRegistry[]`.
Open the reportThe report gives no description here.
Open the reportThe report gives no description here.
Open the reportThe report gives no description here.
Open the reportThe report gives no description here.
Open the reportThe report gives no description here.
Open the reportRegular expressions work by matching patterns in strings. To do this, they often "backtrack" to try different combinations when multiple paths in the pattern could match. This is usually efficient, but certain combinations of patterns and input strings can cause the regex engine to try an exponential number of combinations, leading to what's called catastrophic backtracking. To mitigate the risk of backtracking and ensure the regular expression does not lead to denial of service, consider the following strategies: 1. **Avoid Nested Quantifiers**: Be cautious with the use of quantifiers like `*`, **`+`**, and **`?`**, especially in nested or adjacent positions, as they can often be the source of backtracking issues. 2. **Possessive Quantifiers**: Use possessive quantifiers (e.g., **`++`**, **`+`**) where appropriate, as they prevent backtracking by discarding matches that don't work immediately. 3. **Atomic Grouping**: Use atomic groups **`(?>...)`** to prevent the regex engine from backtracking into the group once a part of it has matched. 4. **Regex Simplification**: Simplify complex regexes where possible. Break down complex expressions into simpler ones, even if it means processing the string in multiple steps. 5. **Timeouts and Limitations**: Implement execution time limits or timeouts for regex evaluations, especially when processing user-provided inputs. The goal is to write regular expressions in a way that ensures they run efficiently, even with challenging input, thereby preventing potential DoS scenarios. Example of potentially vulnerable code: ``` const handleChange = (e: ChangeEvent<HTMLInputElement>) => { const val = e.target.value if (/^-?\d*[.,]?\d*$/.test(val) && /^\d*(\.\d{0,4})?$/.test(val)) { ```
Open the reportThe OpenDollar UI shows incorrect price of the 1 wstETH token, it shows with the rate 1:1 when the actual worth of token is higher. This can confuse and mislead end-users of the application.
Open the reportThe CSP is a security measure that helps in detecting and mitigating certain types of attacks, including Cross-Site Scripting (XSS) and data injection attacks. It's defined via HTTP headers or meta tags in HTML documents and specifies which dynamic resources are allowed to load, thereby preventing attackers from injecting malicious scripts. During our examination of the bot.dev.opendollar.com, app.dev.opendollar.com web application headers and response metadata, we noticed the loose configurations of a Content Security Policy (CSP). This misconfiguration leaves the application vulnerable to XSS attacks, as attackers could potentially inject malicious scripts into the web pages viewed by other users.
Open the reportThe reports name a repository or files. Open a report to see its scope.
Is this your project? Show this record on your own website. The label states what the record holds, links to this page and updates by itself. It is free and needs no sign-in.
Automatic: the three strongest facts of this project’s own record (its last audit and two more), highlighted. They update with the record. Picking a fact turns Automatic off.
<head><script src="https://widget.trustblock.run/project-widget.min.js" defer></script></head><body><divdata-tb-project-widgetdata-tb-project-slug="open-dollar"></div></body>
Paste the code where the label should appear. It uses no API credit and updates by itself.
Something wrong on this page? A missing report, a wrong date, a finding that was fixed since. Tell us and we check it against its source.
Tell us