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: 88/147
Findings: 1
Award: $6.46
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: 0xVolcano
Also found by: 0x11singh99, 0xAadi, 0xAnah, 0xgrbr, 0xhacksmithh, 0xhex, 0xpiken, 0xta, J4X, JCK, K42, Raihan, Rolezn, SAQ, SM3_SS, Sathish9098, SovaSlava, ThreeSigma, Udsen, arjun16, aslanbek, brakelessak, castle_chain, evmboi32, hunter_w3b, lsaudit, naman1778, niser93, nuthan2x, oakcobalt, pavankv, petrichor, phenom80, radev_sw, shamsulhaq123, tabriz, thekmj, unique, yashgoel72, ybansal2403
6.4563 USDC - $6.46
The function is supposed to always revert. Removing the modifier saves 1600 gas on deployment.
order.order_type
is guaranteed to be OrderType.MINT
because of the check at line 169.
if (order.order_type != OrderType.MINT) revert InvalidOrder(); verifyOrder(order, signature); - if (!verifyRoute(route, order.order_type)) revert InvalidRoute(); + if (!verifyRoute(route, OrderType.MINT)) revert InvalidRoute();
| contracts/EthenaMinting.sol:EthenaMinting contract | | | | | | |----------------------------------------------------|-----------------|-------|--------|--------|---------| | Deployment Cost | Deployment Size | | | | | - | 3576457 | 18793 | | | | | + | 3575057 | 18786 | | | | |
getUnvestedAmount()
returns uint256. If it returns anything but zero, the execution reverts.
if (getUnvestedAmount() > 0) revert StillVesting(); // - uint256 newVestingAmount = amount + getUnvestedAmount(); + uint256 newVestingAmount = amount;
function rescueTokens(address token, uint256 amount, address to) external onlyRole(DEFAULT_ADMIN_ROLE) { - if (address(token) == asset()) revert InvalidToken(); + if (token == asset()) revert InvalidToken();
Downcasting to uint64 is absolutely not needed. It limits the space of nonces from 2^256 - 1
to 2^64 - 1
and uses slightly more gas.
- uint256 invalidatorSlot = uint64(nonce) >> 8; + uint256 invalidatorSlot = uint64(nonce) >> 8;
| contracts/EthenaMinting.sol:EthenaMinting contract | | | | | | |----------------------------------------------------|-----------------|-------|--------|--------|---------| | Deployment Cost | Deployment Size | | | | | - | 3576457 | 18793 | | | | | + | 3574657 | 18784 | | | | |
struct UserCooldown { - uint104 cooldownEnd; + uint256 cooldownEnd; uint256 underlyingAmount; }
Remove downcasting:
Change uint104 to uint256:
StakedUSDeV2.blacklist.t.sol#L95
StakedUSDeV2.cooldownEnabled.t.sol#L88
StakedUSDeV2.cooldownEnabled.t.sol#L110
| contracts/StakedUSDeV2.sol:StakedUSDeV2 contract | | | | | | |--------------------------------------------------|-----------------|-------|--------|-------|---------| | Deployment Cost | Deployment Size | | | | | - | 3773992 | 20505 | | | | | + | 3725335 | 20262 | | | | |
EthenaMinting#_deduplicateOrder
either reverts or returns true. The !_deduplicateOrder
check is not needed and error Duplicate()
will never be thrown.
EthenaMinting.sol#L172 EthenaMinting.sol#L203
- if (!_deduplicateOrder(order.benefactor, order.nonce)) revert Duplicate(); + _deduplicateOrder(order.benefactor, order.nonce));
- error Duplicate();
- bytes internal Duplicate = abi.encodeWithSelector(IEthenaMinting.Duplicate.selector);
| contracts/EthenaMinting.sol:EthenaMinting contract | | | | | | |----------------------------------------------------|-----------------|-------|--------|--------|---------| | Deployment Cost | Deployment Size | | | | | - | 3576457 | 18793 | | | | | + | 3555233 | 18687 | | | | |
#0 - c4-pre-sort
2023-11-01T18:48:09Z
raymondfam marked the issue as sufficient quality report
#1 - c4-judge
2023-11-10T20:20:15Z
fatherGoose1 marked the issue as grade-b