-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Weird ERC20 tokens that are used as rewards from Votium will get stuck in the VotiumStrategy
contract
#47
Comments
0xleastwood marked the issue as primary issue |
0xleastwood marked the issue as selected for report |
elmutt (sponsor) confirmed |
@0xleastwood I've covered these cases in L-13 and L-14 of my QA report
Note that the ERC20 transfer issue is also already covered by the automated findings https://gist.github.com/romeroadrian/a2045e828aa87418a66e9ab47d811292 |
Honestly, I interpreted this issue as more than just L-13 and L-14. I thought there was something also being outlined about the |
0xleastwood marked the issue as not selected for report |
0xleastwood changed the severity to QA (Quality Assurance) |
Lines of code
https://github.com/code-423n4/2023-09-asymmetry/blob/main/contracts/strategies/votium/VotiumStrategyCore.sol#L215-L220
https://github.com/code-423n4/2023-09-asymmetry/blob/main/contracts/strategies/votium/VotiumStrategyCore.sol#L280-L291
Vulnerability details
Bug Description
In
VotiumStrategyCore.sol
, thewithdrawStuckTokens()
function is used by the owner to withdraw ERC20 tokens from the Votium contract that are not distributed as reward:VotiumStrategyCore.sol#L215-L220
As seen from above, it uses Openzeppelin's
IERC20
interface to calltransfer()
:IERC20.sol#L41
However, as the interface expects
transfer()
to return abool
,withdrawStuckTokens()
cannot be used to withdraw ERC20 tokens that do not return abool
ontransfer()
. Some examples would include USDT and BNB.When
transfer()
is called, Solidity will attempt to decode the data returned bytransfer()
into abool
due to its interface's definition. However, since these tokens do not have any return value, the data returned will be empty, causingwithdrawStuckTokens()
to revert when attempting to decode its return data.The
applyRewards()
function is used to sell ERC20 tokens from the Votium contract for ETH and distribute them as rewards:VotiumStrategyCore.sol#L280-L291
As seen from above, if the spender's allowance is not
uint256
max, it callsapprove()
to set the spender's allowance to 0 before approving it touint256
max.However, such an implementation will not work for ERC20 tokens that revert on zero value approvals, such as BNB. If
applyRewards()
is called for such a token, the first call toapprove()
would revert, causingapplyRewards()
to revert.Impact
withdrawStuckTokens()
andapplyRewards()
are not be callable for certain ERC20 tokens that do not adhere to the ERC20 standard, which could cause them to become permanently stuck in theVotiumStrategy
contract. This includes widely used tokens such as USDT and BNB.Note that the likelihood of such a token being used as rewards from Votium is not low according to the contest's README:
Recommended Mitigation
Consider using Openzeppelin's SafeERC20 library to handle token transfers and approvals.
Note to judge
I am aware that "Unsafe ERC20 Operations" has been flagged out in the bot report under L-3. However, I have decided to raise it to medium severity, given that Votium might eventually use a weird ERC20 token for rewards in the future, and it will be permanently stuck in the
VotiumStrategy
contract.Note that the C4 docs explicitly states that raising issues from bot reports to a higher severity is fair game, as seen here:
Assessed type
Token-Transfer
The text was updated successfully, but these errors were encountered: