USDE (ERD) security record

Ethereumerd.xyz

As of 3 Nov 2026, USDE (ERD) has 1 audit report on Trustblock, by Quantstamp, dated 30 Oct 2023. That report lists no open critical findings.

Critical findings
No open critical findings
In 1 report.
Open the latest report
Your label, live
Get the label for your site

Record last updated . It holds audits, findings and contracts up to Nov 2026, and incidents up to Oct 2026. Trustblock does not review code.

Audits1

Newest first

AuditSecurity firmDateScopeCritical findingsReport
Ethereum Reserve Dollar (ERD)Security firm: QuantstampDate: Scope: Repository at commit 8023739No open critical findingsOpen · certificate.quantstamp.com

Findings33

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

SeverityOpenAcknowledgedFixed
Critical000
High232
Medium092
Low195
HighFirst Collateral Never Has Its Price UpdatedEthereum Reserve Dollar (ERD) · Quantstamp · 30 Oct 2023Acknowledged

`CollateralManager.priceUpdate()` iterates through the supported collaterals and fetches an updated price from their oracles. However, the for loop starts iterating from index `1`. Nothing in `addCollateral()` prevents any particular collateral type from occupying index `0`. Such a collateral would never have its price updated.

Open the report
HighFlashloans Can Be Used to Siphon Liquidation Rewards Through Active Trove Liquidation MechanismEthereum Reserve Dollar (ERD) · Quantstamp · 30 Oct 2023Acknowledged

A liquidator can open a trove using a flashloan to deposit a large amount of collateral, increasing the number of rewards per unit staked to which they are entitled. In the same transaction they can trigger a liquidation and receive a portion of the redistributed rewards. They can then close their trove, also within the same transaction. This attack effectively steals a portion of the collateral rewards that should be going to existing trove holders. Note that the effectiveness of this attack increases as the size of the liquidation increases and as the amount of the collateral in the system decreases (so that they can more easily get a larger share).

Open the report
HighInsufficient Means for Handling stETH RebasingEthereum Reserve Dollar (ERD) · Quantstamp · 30 Oct 2023Acknowledged

When a user deposits stETH into a trove they recieve eTokens equivalent to the deposit amount. However, stETH rebases such that an address holding stETH will gradually receive more stETH over time. As of now, the codebase does not display any mechanism for allowing borrowers who collateralize stETH to claim these rewards. This will result in excess stETH accumulating in `ActivePool` and `DefaultPool`.

Open the report
MediumPending Debt Rewards Do Not Accrue Interest, Disincentivizing Users From Interacting with ProtocolEthereum Reserve Dollar (ERD) · Quantstamp · 30 Oct 2023Acknowledged

When liquidating a trove, one possibility is for the debt and collateral of that trove to be liquidated across all remaining active troves. This is done by adding the funds to the `DefaultPool` and applying the debt and collateral to an applicable trove (via `TroveManager.applyPendingRewards()`) when it is being adjusted, when it is being closed, and when it is being redeemed against. However, while debt is held in `DefaultPool`, interest is not accrued against it as it does not count towards the debt of an active trove. As a result, it would be in a borrower's interest to, with all else being equal, wait for as long as possible to adjust a trove or close it, as doing so would allow them to avoid paying interest on pending debt rewards.

Open the report
MediumPrivileged Roles and OwnershipEthereum Reserve Dollar (ERD) · Quantstamp · 30 Oct 2023Acknowledged

Privileged roles are used extensively throughout the protocol for the purpose of configuration. However, we have identified a number of functions and roles that can lead to the loss of funds. * `USDEToken`: * `troveManagerAddress` and `borrowerOperationsAddress` can call `mintToTreasury()` and send mint arbitrary amounts of USDE to the `treasuryAddress`. * `stabilityPoolAddress` and `troveManagerLiquidationsAddress` can transfer any amount of USDE tokens between any addresses. * `ActivePool`: The `borrowerOperationsAddress`, `troveManagerAddress`, `stabilityPoolAddress`, `troveManagerRedemptionsAddress`, and `troveManagerLiquidationsAddress` can transfer all held collaterals to the `treasuryAddress` and `liquidityIncentiveAddress`. **All of these addresses can be set and changed by the contract owner.** * `DefaultPool`: The `troveManagerAddress` can transfer all held collaterals to the `activePoolAddress`. **All of these addresses can be set and changed by the contract owner.** * `LiquidityIncentive`: The owner has unrestricted access to transferring the contract's tokens. * `StabilityPool`: `borrowerOperations` has unlimited approval for the contract's `WETH`. **The owner can set and change the `borrowerOperations` address as well as the `WETH` address to another ERC-20 token.** * `Treasury`: The owner has unrestricted access to transferring the contract's tokens.

Open the report
MediumRedemptions and Liquidations Affect Troves in Incorrect OrderEthereum Reserve Dollar (ERD) · Quantstamp · 30 Oct 2023Acknowledged

When a trove is inserted into `SortedTroves`, the ICR is recorded in the trove's corresponding `Node` struct as `Node.ICR`. However, as time passes, this recorded ICR is bound to become inaccurate with regard to the actual trove's ICR—the price of ETH is variable, and so is the amount of debt for which a trove is held responsible. Furthermore, the various collateral types are bound to fluctuate in price as well; notably, rETH is expected to increase in price with respect to time. Therefore, the sorting of the troves according to the stored ICR fields will change from that of a hypothetical sorted list that uses the actual ICR values. It is worth bearing in mind that there exists the `TroveManagerRedemptions.updateTroves()` function that allows the caller to update the trove sorting by reinserting specified troves—each reinsertion involves recording the trove's freshly updated ICR. However, this imposes a significant gas burden for the lifetime of the protocol on whatever parties take on the responsibility of the updating the trove sorting. Moreover, when reinserting the troves, while the ICR of the reinserted trove will be fresh, its location will depend on the potentially stale ICRs recorded in `SortedTroves`. Therefore, keeping the troves in the correct order may require repeatedly updating the ICRs of ALL the nodes in the list. In terms of protocol security, improper sorting of the troves poses a problem because trove sorting is the basis for the correct ordering of liquidations and redemptions: for as long as the sorting remains incorrect, troves are liable to redeemed against in the incorrect order—redemptions are made according to the trove ordering such that troves with lower ICRs (albeit above MCR) are redeemed against first—and liquidations that are made with the sequential liquidation function may liquidate troves in the wrong order (and lower ICR troves may be skipped over). It should be noted that documentation makes the following false statement as well: > Nodes also remain sorted as the ETH:USD price varies, since price fluctuations change the collateral value of each Trove by the same proportion.

Open the report
MediumRemoving Collateral Types Adversely Affects Collateralization RatiosEthereum Reserve Dollar (ERD) · Quantstamp · 30 Oct 2023Acknowledged

The function `CollateralManager.removeCollateral()` removes a collateral type from the list of supported collaterals. Removal of a collateral type could result in a very sudden drop of users' ICRs. To take an extreme example, if a user has deposited only stETH and it becomes unsupported, their ICR would drop to zero. This would have a corresponding effect on TCR as well. The consequent effects may include multiple troves being put up for liquidation simultaneously as well as triggering of recovery mode.

Open the report
MediumRemoving Collateral Types Prevents Collateral WithdrawalEthereum Reserve Dollar (ERD) · Quantstamp · 30 Oct 2023Acknowledged

The function `CollateralManager.removeCollateral()` removes a collateral type from the list of supported collaterals. Once no longer supported, users cannot withdraw their collateral in `BorrowerOperations.withdrawCollateral()`. Any users with a non-zero EToken balance would have no way of reclaiming their collateral. Additionally, if the EToken is changed by calling `CollateralManager.setEToken()`, the total supply of the previous EToken would map to irredeemable collateral. Furthermore, removal of a collateral type could result in a very sudden drop of users' ICRs. To take an extreme example, if a user has deposited only stETH and it becomes unsupported, their ICR would drop to zero. This would have a corresponding effect on TCR as well. Finally, if an EToken is transferred to an address without a trove, such users would be unable to redeem their collateral until they opened a trove.

Open the report
MediumUnchecked Return ValueEthereum Reserve Dollar (ERD) · Quantstamp · 30 Oct 2023Acknowledged

Not checking return values can lead to unintended consequences, especially when the return value indicates the success of a process. Consider the following instances where return values are unchecked: * `BorrowerOperations.sol#257` * `BorrowerOperations.sol#723` * `BorrowerOperations.sol#869` * `BorrowerOperations.sol#871` * `CollateralManager.sol#249` * `CollateralManager.sol#618` * `StETHOracle.sol#276-282` * `StETHOracle.sol#285-301` * `StETHOracle.sol#314-331` * `PriceFeed.sol#613-628` * `PriceFeed.sol#637-643` * `PriceFeed.sol#646-662` * `PriceFeed.sol#674-691` * `StabilityPool.sol#276` * `StabilityPool.sol#1271` * `TroveManager.sol#392-396` * `TroveManager.sol#1270` * `TroveManagerRedemptions.sol#214` * `EToken.sol#104` * `USDEToken.sol#192`

Open the report
MediumUpgrades Can Enable Unexpected Loss of FundsEthereum Reserve Dollar (ERD) · Quantstamp · 30 Oct 2023Acknowledged

All of the collateral in the protocol is stored between `ActivePool` and `DefaultPool`. Both contracts inherit from `OwnableUpgradeable`, which means that both can be upgraded by a user with a privileged role _immediately_. Moreover, both pools' funds can be accessed through other contracts inheriting from `OwnableUpgradeable`, which means if any of these other contracts' owners are compromised, they may also be able to siphon funds from the pools with great speed and ease. This is also possible through updating `EToken`, which is a token that can be used to redeem from troves. The last possibility is also applicable to `USDEToken`; if upgraded in a particular way (say, by letting an owner transfer the tokens indiscriminately), all the tokens can be stolen.

Open the report
Show 10 more
MediumUSDE Debt May Be Misaccounted ForEthereum Reserve Dollar (ERD) · Quantstamp · 30 Oct 2023Acknowledged

Both the `DefaultPool` and `ActivePool` track their USDE debt. The function `increaseUSDEDebt()` will always increase the debt by the full `_amount`. The function `decreaseUSDEDebt()` will decrease its debt by the `min(_amount, USDEDebt)` to prevent underflow. These functions are often used to transfer debt from one pool to another. Given the asymmetry between `increaseUSDEDebt()` and `decreaseUSDEDebt()`, it is possible for a pool to increase its debt by a quantity more than the other pool decreased its debt. This would create a surplus of debt where none exists.

Open the report
MediumUsers Have to Pay Interest on the Borrowing FeeEthereum Reserve Dollar (ERD) · Quantstamp · 30 Oct 2023Acknowledged

Users are charged a borrowing fee that is added to their total USDE Debt, which accumulates interest. However, the borrowing fee is minted immediately to the treasury and is never received by the borrower. The borrowing fee should not accumulate interest as it is not loaned to the borrower.

Open the report
LowApproximate Hints are Generated Sub-OptimallyEthereum Reserve Dollar (ERD) · Quantstamp · 30 Oct 2023Acknowledged

`HintHelpers.getApproxHint()` attempts to generate an approximate hint for the proper placement of a trove in the `SortedTroves` list during insertion. However, it does this based on the ICRs of the troves in `SortedTroves` using price data from the latest oracles' updates. On the other hand, the insertion of the troves into `SortedTroves` is dependent on the ICR of these troves at the time of insertion, and this quantity may be very stale, potentially going back to the time of the first insertion. Therefore, as ICR is bound to change, `getApproxHint()` is not using the best means of discerning a good hint.

Open the report
LowContracts Lack Consolidated InitializationEthereum Reserve Dollar (ERD) · Quantstamp · 30 Oct 2023Acknowledged

Many contracts have both an `initialize()` function as well as a `setAddresses()` function. Almost all of the variable initialization takes place in `setAddresses()` for most contracts. Given that `setAddresses()` can be called more than once, all addresses can be reassigned at the owners discretion. Additionally, some contracts contain an additional `init()` function that initializes variables not assigned in either `initialize()` or in `setAddresses()`. The ability to reassign all variables increases the attack surface in the event of a compromised owner.

Open the report
LowFrontend Functionality May Be Superfluous for ERDEthereum Reserve Dollar (ERD) · Quantstamp · 30 Oct 2023Acknowledged

The frontend functionality in the `StabilityPool` contract with functions such as `registerFrontend()`, `getCompoundedFrontEndStake()`, `_updateFrontEndStakeAndSnapshots` is designed to provide a monetization mechanism for frontends that receive a large amount of user interaction. If the ERD protocol does not intend for their to be a marketplace of front-ends then this functionality is superfluous and may even work against the goals of the developer team.

Open the report
LowInterest Rate Increases as Total Collateralization Rate RisesEthereum Reserve Dollar (ERD) · Quantstamp · 30 Oct 2023Acknowledged

One of the design decisions made for this protocol was to have the variable interest rate increase as the total collateralization rate (TCR) of the protocol increases. We have decided to list this as an issue because in certain market conditions, this may create a positive feedback loop: depositors refuse to withdraw USDE because interest rates are high, leading to even more depositors refusing to withdraw USDE. We acknowledge that the disadvantages of such a setup may not be so severe depending on the following conditions: 1. The majority of USDE will be withdrawn by well-funded borrowers, which will allow them to noticeably influence the interest rate; 1. The typical interest rate is expected to be competitive with regard to interest rates in traditional finance.

Open the report
LowLoss of Precision Due to Division before MultiplicationEthereum Reserve Dollar (ERD) · Quantstamp · 30 Oct 2023Acknowledged

Division before multiplication may result in a loss of precision when the operations are carried over integer numbers. `CollateralManager._calcValue()` contains an example of this at lines 302-309. This issue is found in the following instances: * `CollateralManager.sol#302-309` * `TroveManagerLiquidations.sol#448-450` * `TroveManagerLiquidations.sol#544-546`

Open the report
LowPrice Feed May Unnecessarily Resort to Stale DataEthereum Reserve Dollar (ERD) · Quantstamp · 30 Oct 2023Acknowledged

At `PriceFeed.sol#265`, it is required that both Chainlink and Tellor are working in order for the price to be updated. This means that if Chainlink is restored while Tellor is not, the feed will continue to use the "last good price" instead of proceeding with the latest Chainlink price. The vice versa case is also true: if Tellor is restored while Chainlink is not, the feed will continue to use the "last good price" instead of proceeding with the latest Tellor price. Hence stale data will end up being preferred to fresh data. A similar situation occurs at `PriceFeed.sol#234`, where if Chainlink becomes operational at the same time as Tellor becomes unreliable, fresh Chainlink data will not be used.

Open the report
LowRedemption of Troves with Lower ICR Creates Incentive for Increasing TCREthereum Reserve Dollar (ERD) · Quantstamp · 30 Oct 2023Acknowledged

The trove with the lowest ICR can be redeemed by any user. This creates an incentive for every participant that wants to keep their position open from being the trove with the lowest ICR. This can cause a race to the bottom dynamic which may negate or undermine the incentives created to keep troves as capital efficient as possible.

Open the report
LowRedundant CodeEthereum Reserve Dollar (ERD) · Quantstamp · 30 Oct 2023Acknowledged

When dealing with collateral redemption in the form of eTokens, the protocol often calles `CollateralManger.getShares()` which in turn calls `EToken.getShare()` however, this function simply returns the input, making it a redundant function. This in turn complicates the logic within certain function. Take, for example, the `CollSurplusPool.accountSurplus()` function, which contains the following section: ``` address[] memory collaterals = collateralManager.getCollateralSupport(); uint256[] memory shares = collateralManager.getShares( collaterals, _amount ); ``` The conversion of `_amount` to shares can be entirely removed since this in effect just returns the same array. Furthermore functions such as `getShares()` and `getShare()` in the `CollateralManager` contract can be entirely removed.

Open the report
Show 1 more
LowWhen Oracles Are Down, Stale Prices Are UsedEthereum Reserve Dollar (ERD) · Quantstamp · 30 Oct 2023Acknowledged

In every case where `fetchPrice()` is called, either a price is pulled from an oracle or `lastGoodPrice` is called. Hence if both oracles are down, only the last good price can be resorted to. However, this means that even if both oracles are down or broken for a significant period of time, the last good price will be used indefinitely. This may result in unfavorable conditions for the protocol.

Open the report

Contracts

No deployed address is recorded for these audits.

The reports name a repository or files. Open a report to see its scope.

The repositories and files the reports name

Show this on your site

Is this your project? Show this record on your own website. The label states what the record holds, links to this page and updates by itself. It is free and needs no sign-in.

Content

Facts

Automatic: the three strongest facts of this project’s own record (its last audit and two more), highlighted. They update with the record. Picking a fact turns Automatic off.

Fixed as
Language

Style

Layout
Theme
Accent
Corners

Format

Size
Date
Embed as
HTML
<head>
<script src="https://widget.trustblock.run/project-widget.min.js" defer></script>
</head>
<body>
<div
data-tb-project-widget
data-tb-project-slug="usde-erd"
></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