Platform: Code4rena
Start Date: 21/11/2022
Pot Size: $90,500 USDC
Total HM: 18
Participants: 101
Period: 7 days
Judge: Picodes
Total Solo HM: 4
Id: 183
League: ETH
Rank: 32/101
Findings: 4
Award: $190.31
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: xiaoming90
Also found by: 0xSmartContract, 8olidity, PaludoX0, Ruhum, adriro, bin2chen, cccz, koxuan, ladboy233, pashov, poirots, rvierdiiev, unforgiven
83.2606 USDC - $83.26
In both contracts, the previewWithdraw
function has the same body
// Calculate shares based on the specified assets' proportion of the pool uint256 shares = convertToShares(assets); // Save 1 SLOAD uint256 _totalSupply = totalSupply; // Factor in additional shares to fulfill withdrawal if user is not the last to withdraw return (_totalSupply == 0 || _totalSupply - shares == 0) ? shares : (shares * FEE_DENOMINATOR) / (FEE_DENOMINATOR - withdrawalPenalty);
The problem is that the ERC4626 standard specifically requires previewWithdraw
to round up, while this code does not do so - actually convertToShares
rounds down.
previewWithdraw
returns the amount of shares that would be burned to withdraw specific amount of asset. Thus, the amount of shares must to be rounded up, so that the vault won't be shortchanged.
Since contracts are not compliant with a standard this can result in some integration issues and in this particular case it can also result in a wrong amount returned from previewWithdraw
which won’t actually work with withdraw
, so it can cause lots of reverted transactions. Medium severity is appropriate here.
Make the previewWithdraw
method round up, the same way it does in PirexERC4626.sol
#0 - c4-judge
2022-12-03T18:11:10Z
Picodes marked the issue as duplicate of #264
#1 - c4-judge
2022-12-03T18:11:15Z
Picodes marked the issue as partial-50
#2 - Picodes
2022-12-03T18:11:38Z
Finding is correct but does not show this could eventually lead to a loss of user funds
#3 - c4-judge
2023-01-01T11:34:17Z
Picodes changed the severity to 3 (High Risk)
#4 - C4-Staff
2023-01-10T21:57:30Z
JeeberC4 marked the issue as duplicate of #264
#5 - liveactionllama
2023-01-11T18:42:43Z
Duplicate of #178
🌟 Selected for report: Jeiwan
Also found by: 0xLad, 0xSmartContract, 8olidity, HE1M, JohnSmith, KingNFT, Koolex, Lambda, R2, __141345__, carrotsmuggler, cccz, gogo, hl_, joestakey, koxuan, ladboy233, pashov, peanuts, rbserver, rvierdiiev, seyni, unforgiven, xiaoming90, yongskiws
25.3241 USDC - $25.32
The normal ERC4626 implementation (which is not changed in the repository) has a vulnerability which can result in the first depositor stealing every subsequent depositor’s funds.
It works like this:
underlying
, so he now holds 1 shareunderlying
underlying
balance for his 1 share (the total supply) resulting in him stealing all of Alice’s deposited tokensThis can result in a 100% loss of deposited funds for users of the protocol, so it should be of High severity.
Revert when the shares minted are zero.
#0 - c4-judge
2022-12-03T16:14:47Z
Picodes marked the issue as duplicate of #407
#1 - c4-judge
2023-01-01T10:45:26Z
Picodes marked the issue as satisfactory
#2 - C4-Staff
2023-01-10T21:54:30Z
JeeberC4 marked the issue as duplicate of #275
🌟 Selected for report: deliriusz
Also found by: 0x52, 0xLad, 0xbepresent, Englave, R2, Ruhum, cccz, gzeon, hihen, keccak123, ladboy233, pashov, pedroais, perseverancesuccess, rbserver, rvierdiiev, simon135, unforgiven, wagmi, xiaoming90
15.9293 USDC - $15.93
The compound
method has the amountOutMinimum
parameter, which basically serves as the slippage tolerance parameter. The problem is that everywhere in the code where compound
is called, the value of amountOutMinimum
is just 1 wei, which basically means all swaps executed in the compound
method can be sandwiched and the user can lose a huge amount of value due to slippage.
This vulnerability can easily be exploited by a MEV bot that is scouting the public mempool. Setting severity to Medium because that’s what MEV attacks usually get rated as.
Add a setter to dynamically configure slippage tolerance amounts on-chain, or always make sure all transactions go through a private/dark mempool
#0 - c4-judge
2022-12-03T21:49:56Z
Picodes marked the issue as duplicate of #183
#1 - c4-judge
2022-12-30T20:53:41Z
Picodes marked the issue as duplicate of #185
#2 - c4-judge
2023-01-01T10:45:35Z
Picodes marked the issue as satisfactory
#3 - C4-Staff
2023-01-10T22:10:37Z
JeeberC4 marked the issue as duplicate of #137
🌟 Selected for report: Jeiwan
Also found by: 0xbepresent, Koolex, __141345__, cryptoDave, cryptonue, datapunk, pashov, unforgiven
65.8012 USDC - $65.80
The claim
method in PirexRewards
iterates over the rewardTokens
array for a producerToken
. Now this array is completely managed by the contract’s owner
who can call addRewardToken
which pushes a new value in that array, as many times as he decides with whatever value he decides.
Let’s look at the following scenario:
addRewardToken
a huge amount of times, which results in the rewardTokens
array being hugeclaim
the code will take a crazy amount of gas, because it has to iterate over the whole rewardTokens
array. Since the amount of gas will possibly be more than the block gas limit, this results in a DoS and the user won’t be able to claim.Or this scenario:
addRewardToken
with an address that is not really a tokenclaim
the code will try to do a call to producer.claimUserReward
giving the address of the rewardToken
, but since it is not really a token (or maybe it is just a random address with no bytecode) the call will revert. Actually it will always revert, which is a DoS state.This is a centralisation vulnerability allowing the owner to stop the user rewards anytime. Since it requires a malicious/compromised owner it is Medium severity
Add a way for the user to claim rewards only from a token he chooses, not to have to go through all reward tokens on each claim.
#0 - drahrealm
2022-12-08T05:25:07Z
Related to issue #271 and also a centralization issue.
#1 - c4-sponsor
2022-12-08T05:25:19Z
drahrealm marked the issue as disagree with severity
#2 - Picodes
2022-12-26T13:28:47Z
Although I do agree with the warden's mitigation that it'd be interesting for users to have the option to claim only for the token he chooses, currently the call to claimUserReward
does not revert if the token address is incorrect, so the call would not revert. Duplicate #271 with partial credit as the warden identified the weak point but the scenario described are very unlikely or do not work
#3 - c4-judge
2022-12-26T13:28:56Z
Picodes marked the issue as duplicate of #271
#4 - c4-judge
2022-12-26T13:29:06Z
Picodes marked the issue as partial-50