Both of these issues stem from the same set of functions (addToBlacklist() and removeFromBlacklist()), which handle blacklisting operations in the contract.
Misleading NatSpec comments for roles
In the provided code for the addToBlacklist() and removeFromBlacklist() functions, the NatSpec comments imply that the DEFAULT_ADMIN_ROLE can directly interact with these functions. However, in reality, the DEFAULT_ADMIN_ROLE has the ability to control blacklisting indirectly by manipulating roles using the grantRole() and revokeRole() functions.
This misleading documentation also hides the potential risk mentioned in the second issue where the DEFAULT_ADMIN_ROLE might inadvertently blacklist itself.
Potential for DEFAULT_ADMIN_ROLE to blacklist itself
An oversight exists where the DEFAULT_ADMIN_ROLE might blacklist itself, via the grantRole() function. While the addToBlacklist() function does have the notOwner() protection modifier, if it is genuinely intended that the DEFAULT_ADMIN_ROLE should also be able to blacklist but simultaneously be protected from blacklisting itself, additional logic is required. This could be achieved by overriding the _grantRole() function to include checks ensuring the owner does not blacklist themselves.
Impact
Misleading documentation can cause developers or external integrators to misuse or misinterpret the functions.
If the DEFAULT_ADMIN_ROLE can blacklist itself, it could render the admin ineffective, potentially stopping essential functions of the contract.
Proof of Concept
A user with the DEFAULT_ADMIN_ROLE attempts to use the addToBlacklist() and removeFromBlacklist() functions, but the calls are reverted.
A user with the DEFAULT_ADMIN_ROLE employs the grantRole() function and sets themselves as fully restricted.
Tools Used
Manual review
Recommended Mitigation Steps
Accurately update the NatSpec comments to reflect the capabilities of the DEFAULT_ADMIN_ROLE.
Implement checks to prevent the DEFAULT_ADMIN_ROLE from blacklisting themselves.
Override the _grantRole() function and incorporate the necessary checks to make sure only the intended addresses can be assigned specific roles.
Lines of code
https://github.com/code-423n4/2023-10-ethena/blob/main/contracts/StakedUSDe.sol#L106-L109 https://github.com/code-423n4/2023-10-ethena/blob/main/contracts/StakedUSDe.sol#L120-L123
Vulnerability details
Both of these issues stem from the same set of functions (
addToBlacklist()
andremoveFromBlacklist()
), which handle blacklisting operations in the contract.Misleading NatSpec comments for roles
In the provided code for the
addToBlacklist()
andremoveFromBlacklist()
functions, the NatSpec comments imply that theDEFAULT_ADMIN_ROLE
can directly interact with these functions. However, in reality, theDEFAULT_ADMIN_ROLE
has the ability to control blacklisting indirectly by manipulating roles using thegrantRole()
andrevokeRole()
functions. This misleading documentation also hides the potential risk mentioned in the second issue where theDEFAULT_ADMIN_ROLE
might inadvertently blacklist itself.Potential for
DEFAULT_ADMIN_ROLE
to blacklist itselfAn oversight exists where the
DEFAULT_ADMIN_ROLE
might blacklist itself, via thegrantRole()
function. While theaddToBlacklist()
function does have thenotOwner()
protection modifier, if it is genuinely intended that theDEFAULT_ADMIN_ROLE
should also be able to blacklist but simultaneously be protected from blacklisting itself, additional logic is required. This could be achieved by overriding the_grantRole()
function to include checks ensuring the owner does not blacklist themselves.Impact
DEFAULT_ADMIN_ROLE
can blacklist itself, it could render the admin ineffective, potentially stopping essential functions of the contract.Proof of Concept
DEFAULT_ADMIN_ROLE
attempts to use theaddToBlacklist()
andremoveFromBlacklist()
functions, but the calls are reverted.DEFAULT_ADMIN_ROLE
employs thegrantRole()
function and sets themselves as fully restricted.Tools Used
Manual review
Recommended Mitigation Steps
DEFAULT_ADMIN_ROLE
.DEFAULT_ADMIN_ROLE
from blacklisting themselves._grantRole()
function and incorporate the necessary checks to make sure only the intended addresses can be assigned specific roles.Assessed type
Invalid Validation