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: 104/147
Findings: 1
Award: $4.52
🌟 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
Count | Explanation |
---|---|
[L-01] | Multiple Issues can occur while using stETH in EthenaMinting |
[L-02] | Accidental/Deliberate griefing Attack possible in StakedUSDeV2 |
[L-03] | Malicious User can frontrun to avoid getting Blacklisted |
Total Low Risk Issues | 3 |
---|
Count | Explanation |
---|---|
[N-01] | Improvement in verifyRoute function in EthenaMinting |
Total Non-Critical Issues | 1 |
---|
stETH
in EthenaMinting
To start off, asset
used to mint USDe
will be stETH
which is a rebasing token. So it can lead to 2 following issues:
Assume Alice signed a transaction to mint USDe
for x
amount of stETH
. While the transaction is in mempool, rebase occurs and:
If positive rebase occurs (most likely)
x
amount of stETH
which was originally thought off, leading to loss of funds for Protocol.If negative rebase occurs
stETH
:stETH
to User B.stETH
balance gets converted to shares, integer division happens and rounding down applies using formula: shares[account] = balanceOf(account) * totalShares / totalPooledEther
.In this example, User A is user and User B is custodian Address. So in case custodian address is a contract where further logics are used to allocate this funds, it can break the assumption that exact value of stETH
has been transferred.
These are common issues for protocol integrating stETH
with their logic. That is why, Lido has provided solution for it.
Use transferShares
instead of using transferfrom
while transfering stETH
because during Rebasing event, underlying shares remain same but the balance of stETH
can increase or decrease.
This Solves:
stETH
.Lido has officially recommended this in their doc here which I would recommend you to go through.
When integrating stETH as a token into any dApp, it's highly recommended to store and operate shares rather than stETH public balances directly, because stETH balances change both upon transfers, mints/burns, and rebases, while shares balances can only change upon transfers and mints/burns.
StakedUSDeV2
During Cooldown ON
State of StakedUSDeV2
, Anyone with allowance from a User can call cooldownAssets
on User's behalf.
Consider the following scenario:
USDe
in the vault and got some stUSDe
minted for her.stUSDe
itself is an ERC20
standard token, Alice gives allowance to use some amount of stUSDe
to someone else let's say Bob.cooldownAssets
making her cooldownEnd
time as 90 days (considering default cooldownDuration
).cooldownAssets
with the smaller amount and owner
as Alice to increase the cooldownEnd
period my another 90 days. In worst case, Bob can call it on 90th day which increase the cooldownEnd
period to effectively 180 days for Alice.File: StakedUSDeV2.sol function cooldownAssets(uint256 assets, address owner) external ensureCooldownOn returns (uint256) { // @audit Griefing Attack Possible with allowance from owner 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); return shares; }
2 Options:
owner
addresses, instead use cooldowns[msg.sender]
to update state variables.Here's how:
BLACKLIST_MANAGER_ROLE
has power to blacklist any address.addToBlacklist
with Alice's address.This way any User can manage to avoid getting blacklisted. Possible solution here is to use Flashbots to privately add this transaction to blockchain.
verifyRoute
function in EthenaMinting
verifyRoute
is called only in mint
function where the funds from the user can be passed to the different custodianAddresses
.
So it is unnecessary to check the order type here as it can never be OrderType.REDEEM
. So it is unnecessary check which can be removed.
File: EthenaMinting.sol function verifyRoute(Route calldata route, OrderType orderType) public view override returns (bool) { // routes only used to mint @-> if (orderType == OrderType.REDEEM) { return true; } //---SNIP----// }
#0 - c4-pre-sort
2023-11-02T01:27:44Z
raymondfam marked the issue as sufficient quality report
#1 - c4-judge
2023-11-14T17:11:26Z
fatherGoose1 marked the issue as grade-b