Quantstamp reviewed Ethena (Ethena Labs) on 28 Sep 2023: 13 findings, 0 critical; 9 marked fixed, 4 acknowledged.
Report hosted on certificate.quantstamp.com.
Trustblock does not review code.
Statuses are the security firm’s own, from its report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 0 |
| High | 0 | 0 | 0 |
| Medium | 0 | 2 | 2 |
| Low | 0 | 2 | 7 |
When `order.benefector` is a smart contract, it can delegate an EOA to be the signer for the contract, by calling `setDelegatedSigner()`. When `mint()` and `redeem()` are called, they first check that the order is valid by calling `validateOrder()`, which in turn checks that the signer of the order is either `msg.sender` or a delegated signer for `msg.sender` (i.e. `delegatedSigner[signer] == order.benefactor`). Suppose contract A delegates Alice to be the signer by calling `delegateSigner(Alice)`, this would result in `delegatedSigner[Alice] = A`. However, since `setDelegatedSigner()` can be called by anyone, this allows a malicious actor, Bob, to block any `mint()` or `redeem()` calls for contract A (signed by Alice) by front-running it with a call `delegateSigner(Alice)`, which would set `delegatedSigner[Alice] = Bob`, causing `verifyOrder()` to fail.
The system does not support using native ETH as collateral to mint new USDe, as shown in `_transferCollateral()`. However, it seems possible for users to redeem native tokens since `_transferToBeneficiary()` supports it. Furthermore, there is no direct way (other than `selfdestruct()`) for the contract to receive native tokens as `fallback()` and `receive()` are not implemented and there is no payable function.
`getRsv()` is defined in `EthenaMinting.sol` to help unpack `r,s,v` from the signature bytes. It is recommended to use existing battle-tested libraries (e.g. OpenZepplin's ECDSA library) for cryptographic operations due to the high risk of introducing unintended vulnerabilities.
Consider the following input validation checks: 1. `EthenaMinting.sol` 1. `setUSDe()` 1. Check that `_usde` is not the same as `usde`. 2. `StakeUSDeV2.sol` 1. `setCooldownDuration()` 1. `duration` should not exceed the specified 90-day maximum cooldown. 1. `unstake()` 1. `receiver` should not be the zero address.
If the owner renounces their ownership, all ownable contracts will be left without an owner. Consequently, any function guarded by the `onlyOwner` modifier will no longer be able to be executed. Additionally, the DEFAULT_ADMIN_ROLE can be renounced/revoked from `EthenaMinting` and `StakeUSDe.sol`.
There is the potential for collateral to be transferred to addresses that are not controlled by the team as there is no storage in the contract state that contains a set of these addresses that are valid. As a result, there is the potential for USDe-Buy-Orders to be processed that do not transfer the collateral to a team-controlled address. While it is understood that Ethena servers perform validation before sending transactions to the smart contract, we would still like to highlight this possibility.
`EthenaMinting.mint()` does not confirm that the order type being processed is indeed of `OrderType.MINT`. In the case where an Order with `OrderType.REDEEM` is passed to this function, `verifyRoute()` will not validate matching lengths of the `route.addresses` and `route.ratios`, which will result in index out of bounds when transferring collateral. This will lead to a failing transaction without adequate failure logging.
`ecrecover()` is used to recover the signer of a message. If the recovery fails, `ecrecover()` will return the zero address. This can lead to unintended consequences and therefore, the call should revert if the zero address is returned.
The rewarder can artificially reduce the vesting rate by transferring in rewards with `transferInRewards()` while previous rewards are still vesting. For example, let's assume `VESTING PERIOD = 1 hour` and the initial reward is `600`, so the current rate of vesting is `10` tokens per minute. Then, after 30 minutes pass, the rewarder transfers in another `60` token as a reward. This means the unvested amount is now `360`, which leads to a vesting rate of `6` tokens per minute. However, users should be entitled to the `10` tokens per minute rate for the remaining `300` tokens reward from the initial transfer.
The report names a repository or files. Open the report to see its scope.
Repository and files the report names (3)
236 projects reviewed · 332 reports · latest Oct 2026
See Quantstamp’s auditsSomething 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