Platform: Code4rena
Start Date: 24/10/2023
Pot Size: $36,500 USDC
Total HM: 4
Participants: 147
Period: 6 days
Judge: 0xDjango
Id: 299
League: ETH
Rank: 59/147
Findings: 2
Award: $93.25
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: 0xmystery
Also found by: 0x11singh99, 0xAadi, 0xAlix2, 0xG0P1, 0xStalin, 0xWaitress, 0x_Scar, 0xhacksmithh, 0xhunter, 0xpiken, Al-Qa-qa, Arz, Avci, Bauchibred, BeliSesir, Breeje, Bughunter101, DarkTower, Eeyore, Fitro, HChang26, Imlazy0ne, J4X, JCK, Kaysoft, Kral01, Madalad, Mike_Bello90, Noro, PASCAL, PENGUN, Proxy, Rickard, Shubham, SovaSlava, Strausses, Team_Rocket, ThreeSigma, Topmark, Udsen, Walter, Yanchuan, Zach_166, ZanyBonzy, adam-idarrha, adeolu, almurhasan, arjun16, ast3ros, asui, ayden, btk, cartlex_, castle_chain, cccz, chainsnake, codynhat, critical-or-high, cryptonue, csanuragjain, deepkin, degensec, dirk_y, erebus, foxb868, ge6a, hunter_w3b, jasonxiale, kkkmmmsk, lanrebayode77, lsaudit, marchev, matrix_0wl, max10afternoon, nuthan2x, oakcobalt, oxchsyston, pavankv, peanuts, pep7siup, pipidu83, pontifex, ptsanev, qpzm, radev_sw, rokinot, rotcivegaf, rvierdiiev, sorrynotsorry, squeaky_cactus, supersizer0x, tnquanghuy0512, twcctop, twicek, young, zhaojie, ziyou-
4.5226 USDC - $4.52
In USDeSilo.sol
file, SafeERC20
lib is imported and is declared to be used for IERC20
variables (#L13), but it is not used at any part of the code.
This can cause misunderstanding for people when seeing the code, as they may think that SafeERC20
lib functions will be used in the contract.
You should remove the import statement as well as the line declaring its usage as it is not important.
Lines to remove in USDeSilo.sol
: (#L13, #L5)
In EthenaMinting.sol
the totalRatio, which is used by the Ethena to validate routes in EthenaMinting::verifyRoute
, is 10_000
. This value used twice by the devs in two different positions in the EthenaMinting.sol
: (#L370, #L425)
Inconsistency and potential confusion during code reviews and maintenance
It is better to save these kinds of variables as constant and use them when needed. This will help improve code syntax and readability, and avoid syntax errors.
For example, we can name a variable TOTAL_RATIO
and set its value to 10_000
, and use the variable when needed.
uint256 private constant TOTAL_RATIO = 10_000;
In EthenaMinting.sol
, encodeRoute(Route)
function is declared but it is not used in the protocol.
This function was used when there was a wrong EIP712 signature implementation for Route
, But the protocol removed it when figuring out that it was implemented wrongly by the previous audit done of the protocol by Pashov.
The reference for removing using this function from pashov audits: the discussion for this issue.
Protocol devs forgot to remove the function body, they removed the calling only. So it is unused now, which can lead to misleading, and additional gas costs when deploying the contract.
Remove the declaration of this function in EthenaMinting.sol
: #L334-L336
In EthenaMinting.sol
, there are unnecessary checks for zero addresses in the following functions:
These two functions check if the _custodianAddresses
contains the following assets or not. And when adding and new address to _custodianAddresses
checking for address(0) is done,
so we are sure that the _custodianAddresses
will not have an address(0), so its unnecessary to check for address(0) twice.
This will make code syntax look better, in addition to saving gas when executing these two functions.
Remove checking for address(0) in the two functions we mentioned above.
In StakedUSDe.sol
, these two functions cooldownAssets()
and cooldownShares()
have a common syntax for making a withdrawal request. It is better to refactor the code syntax to improve functions readability and improve code syntax.
1- Make a new function called _withdrawAssets
for example, and add reused code in it.
// StakedUSDe.sol function _withdrawAssets(address owner, uint256 assets, uint256 shares) private { cooldowns[owner].cooldownEnd = uint104(block.timestamp) + cooldownDuration; cooldowns[owner].underlyingAmount += assets; _withdraw(_msgSender(), address(silo), owner, assets, shares); }
2- Remove the reused code from cooldownAssets()
and cooldownShares()
functions, then add the new function we created instead.
// StakedUSDe.sol function cooldownAssets(uint256 assets, address owner) external ensureCooldownOn returns (uint256) { if (assets > maxWithdraw(owner)) revert ExcessiveWithdrawAmount(); uint256 shares = previewWithdraw(assets); - cooldowns[owner].cooldownEnd = uint104(block.timestamp) + cooldownDuration; - cooldowns[owner].underlyingAmount += assets; - _withdraw(_msgSender(), address(silo), owner, assets, shares); + _withdrawAssets(owner,assets, shares); return shares; }
// StakedUSDe.sol function cooldownShares(uint256 shares, address owner) external ensureCooldownOn returns (uint256) { if (shares > maxRedeem(owner)) revert ExcessiveRedeemAmount(); uint256 assets = previewRedeem(shares); - cooldowns[owner].cooldownEnd = uint104(block.timestamp) + cooldownDuration; - cooldowns[owner].underlyingAmount += assets; - _withdraw(_msgSender(), address(silo), owner, assets, shares); + _withdrawAssets(owner,assets, shares); return shares; }
constant
keywordIt seems developers forgot to put constant keyword in MAX_COOLDOWN_DURATION
variable in the StakedUSDeV2.sol
#L22, as it's in UPPERCASE syntax, and its value is unchangeable.
Add constant keyword before the variable name in StakedUSDeV2.sol
.
- uint24 public MAX_COOLDOWN_DURATION = 90 days; + uint24 public constant MAX_COOLDOWN_DURATION = 90 days;
NatScep syntax is preceded by triple slashes, in order for the code editor to know it and format the comment.
In EthenaMinting.sol
, there is wrong commenting syntax #L68.
You should follow the commenting syntax pattern to improve readability.
Add an additional slash to follow the commenting sytax.
#0 - c4-pre-sort
2023-11-02T02:53:03Z
raymondfam marked the issue as sufficient quality report
#1 - c4-judge
2023-11-14T16:59:20Z
fatherGoose1 marked the issue as grade-b
🌟 Selected for report: radev_sw
Also found by: 0xSmartContract, 0xweb3boy, Al-Qa-qa, Bauchibred, Bulletprime, D_Auditor, J4X, JCK, K42, Kral01, Sathish9098, ZanyBonzy, albahaca, catellatech, clara, digitizeworx, fouzantanveer, hunter_w3b, invitedtea, jauvany, oakcobalt, pavankv, peanuts, xiao
88.7348 USDC - $88.73
List | Title | Description |
---|---|---|
1 | Overview of the EthenaLabs protocol | Services and Features provided by the protocol |
2 | System Overview | Detailing the parts of the system and explaining each part separately |
3 | System Architecture | Explaining the Architecture Used by EthenaLabs to Achieve their Goal |
4 | Documentation | Overview of the documentation and its quality |
5 | Centralization Risks | Risks that should be taken into consideration |
6 | Learnings from this Audit | New concepts and information I learned from auditing EthenaLabs protocol |
7 | My view on the project | My opinion about the protocol's success when it launches |
8 | Time spent on analysis | The total time I spent analyzing and auditing the codebase |
EthenaLabs is a stable value crypto token tied to dollar value. Ethenalab team thinks about the problems related to the stable crypto tokens tied to the dollar and managed to solve this problem using different solutions and approaches.
What makes EthenaLabs dollar different from other stable dollar tokens, is their mechanism to achieve stability. The stability of the dollar is not achieved by saving dollars as collateral equal to the tokens minted like USDC or USDT, nor it is achieved by cryptocurrencies collaterals that exceed their price like DAI. The dollar achieves its stability value using Delta-Neutral Stability.
In brief, the protocol uses Staked Ethereum tokens (stETH) to mint new dollars, and with these tokens, he makes short tradings for these ETHUSD perpetual in Off-Exchange Settlement.
So if the ETH price goes down, which means the collateral value decreases, short Ethereum perpetual will make profits, which will compensate for the loss of Ethereum collateral value.
If the other thing happens, and the Ethereum price goes up, the collateral value increases, but this will not increase the value of the Protocol dollar token (USDe), since the Short Ethereum perpetual is losing in this situation, so it will be neutral.
Another feature the protocol offers is Yeild Generation, Let's see how the protocol is making money.
The protocol generates yields in two ways:
The protocol provides a staking solution for USDe holders, they can put their dollars in the contract, participate in the yield generation, and earn money.
EthenaLabs will not make users cover the loss if the yields are negative. knowing that the yields calculated by the protocol in the previous months and years are kind of hard to become negative, because of the delta-neutral strategy, in addition to fees, and yields generated when staking Ethereum.
After we take a look at the protocol and its functionality and features, let's dive into the system itself, and know how it works.
The System consists of 3 core functionality:
SingleAdminAccessControl.sol
ADMIN_ROLE
can give people other roles like MINTER_ROLE
.ADMIN_ROLE
can be changed from one address to another.ADMIN_ROLE
.USDe.sol
minter
.ADMIN_ROLE
which has the ability to change the minter
address.USDe holder
: can transfer tokens in addition to burning them.EthenaMinting.sol
MINTER_ROLE
can mint new tokens, and only REDEEMER_ROLE
can redeem tokens.maxMintPerBlock
, and the number of tokens to redeem should not exceed maxRedeemPerBlock
.ADMIN_ROLE
can change maxMintPerBlock
value, and maxRedeemPerBlock
value, add/remove Supported assets (tokens) to be used as collaterals, add/remove Custodian Addresses (The addresses that will take the collaterals Off-Exchange
).GATE_KEEPER
can add/remove MINTER_ROLE
or REDEEM_ROLE
.ADMIN_ROLE
can add/remove any role.StakedUSDe.sol
SOFT_RESTRICTED_STAKER_ROLE
address can't stake his USDe tokens or get stUSDe tokens minted to himFULL_RESTRICTED_STAKER_ROLE
address can't burn his stUSDe tokens to unstake his USDe tokens, neither to transfer stUSDe tokens. His balance can be manipulated by the ADMIN_ROLE
address.BLACKLIST_MANAGER_ROLE
can restrict users either make them SOFT_RESTRICTED_STAKER_ROLE
or FULL_RESTRICTED_STAKER_ROLE
.ADMIN_ROLE
can transfer any ERC20 tokens locked in the contract except USDe.StakedUSDeV2.sol
StakedUSDe.sol
, but with the ability to add a period that users should wait in order to unstake their USDe tokens.USDeSile.sol
contract, and can only be claimed by the user if the period (cooldown) passes.ADMIN_ROLE
can change the cooldown period, but its maximum is 90 days.USDeSilo.sol
StakedUSDeV2.sol
.The system relies on a combination of blockchain technology, Web development technology, and Trading Companies.
EthenaLabs should be sure of the safety of the servers they are relying on, and the trading platforms they are using, since they are part of the all system of the protocol. If one of these things gets compromised it may lead to the breaking of the token system.
EthenaLabs provides good and detailed documentation, which makes it easy to understand how the system works. They also provide a good explanation for the common processes that will be made by users like minting and staking, they provide a video guide, in addition to written documentation.
The documentation is great for understanding the workflow of the system, and how to use it. However the documentation for the smart contract code itself is not detailed, there is no reference for smart contracts explaining each smart contract (.sol) file usage, functions, and variables. This makes the auditing process harder, and updating the system (protocol) in the future may be harder too, because of a lack of detailed code documentation.
Unfortunately, I found that code comments are not detailed, like the technical documentation too, this is not a good thing, as it will be hard to understand what functions do. Some functions have comments that explain their functionality, and how they work, but others don't.
As we said in the Architecture section, the system relies on three different technologies: Blockchain, Web2, and trading platforms. This makes the system easier to compromise. The hackers now have 3 different options if they succeed in breaking one of them, the system will be broken.
The system relies heavily on trusted roles, it uses a lot of roles to manage the system in a bureaucratic way, so if one Authorized role gets compromised, it can compromise the roles below it.
The system has a very important role which is ADMIN_ROLE
, any anyone reaches the information of this address, and succeeds in controlling it, the system is over.
ADMIN_ROLE
: Controls all the system.MINTER_ROLE
: can mint any number of tokens that not exceeding maxMintPerBlock
each block.REDEEMER_ROLE
: can redeem any number of tokens that not exceeding maxRedeemPerBlock each block.GATE_KEEPER
: can add/remove MINTER_ROLE
or REDEEMER_ROLE
.BLACKLIST_MANAGER_ROLE
: can block users from staking or withdrawing their tokens in the staking contract.Our journey in auditing and analyzing EthenaLabs protocol code gave us a lot of valuable information.
ERC4626
, and OpenZeppelin implementation for it.The project offers a stable ERC20 token tied to dollar values with the same value of collaterals to pay in order to get some tokens, this is great as it can attract people to use it as it is decentralized, you don't need to pay an excess amount in order to get dollars, so it providers a great user experience for users.
The protocol allows users to stake their USDe to earn more money, this can encourage people to mint tokens, and enjoy the staking process. Since the protocol team promised to bear the loss in negative yield, this can encourage people to stake their tokens as they will either win or in the worst case no win and no lose (neutral).
Although the benefits of the system are great there are some points I think can make people less addicted to using this protocol.
minter
to mint any amount of tokens he wants to can make people worry about minting more tokens which can cause inflation.BLACKLIST_MANAGER_ROLE
can freeze staker tokens, will make people afraid of participating in the staking process.I spent 4 days auditing and analyzing the codebase, with a total hours ~20 Hours.
20 hours
#0 - c4-pre-sort
2023-11-01T14:21:47Z
raymondfam marked the issue as sufficient quality report
#1 - c4-judge
2023-11-10T19:37:29Z
fatherGoose1 marked the issue as grade-a