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: 27/101
Findings: 3
Award: $224.74
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: Jeiwan
Also found by: 0xbepresent, Koolex, __141345__, cryptoDave, cryptonue, datapunk, pashov, unforgiven
131.6023 USDC - $131.60
https://github.com/code-423n4/2022-11-redactedcartel/blob/03b71a8d395c02324cb9fdaf92401357da5b19d1/src/PirexRewards.sol#L179 https://github.com/code-423n4/2022-11-redactedcartel/blob/03b71a8d395c02324cb9fdaf92401357da5b19d1/src/PirexRewards.sol#L387
Any unclaimed rewardTokens will be unclaimable once a rewardToken
has been removed from producerTokens[producerToken].rewardTokens
list.
The owner can call removeRewardToken
to remove any rewardToken
from a producerToken
. However, if the rewardToken
still has unclaimed rewards, as evidenced by producerTokens[producerToken].rewardStates
, these rewards will be unclaimable.
The claim
function, once identified the producerToken
, loops through rewardTokens
list and claims rewards as marked in rewardStates[rewardToken]
. However, if a rewardToken has been removed, even if rewardStates[rewardToken]
is non-zero, it would not be claimable.
manual
Check require(rewardStates[rewardTokens[removalIndex]] == 0)
before removing the unwanted rewardToken.
#0 - c4-judge
2022-12-03T20:43:39Z
Picodes marked the issue as duplicate of #255
#1 - c4-judge
2022-12-05T10:38:57Z
Picodes marked the issue as duplicate of #255
#2 - c4-judge
2023-01-01T10:39:59Z
Picodes marked the issue as duplicate of #271
#3 - c4-judge
2023-01-01T11:11:10Z
Picodes changed the severity to 2 (Med Risk)
#4 - c4-judge
2023-01-01T11:11:12Z
Picodes marked the issue as satisfactory
🌟 Selected for report: 0xSmartContract
Also found by: 0xAgro, 0xNazgul, 0xPanda, 0xbepresent, 0xfuje, Awesome, B2, Bnke0x0, Deivitto, Diana, Funen, Jeiwan, JohnSmith, Josiah, R2, RaymondFam, Rolezn, Sathish9098, Waze, adriro, aphak5010, brgltd, btk, carrotsmuggler, ch0bu, chaduke, codeislight, codexploder, cryptostellar5, csanuragjain, danyams, datapunk, delfin454000, deliriusz, eierina, erictee, fatherOfBlocks, gz627, gzeon, hansfriese, hihen, jadezti, joestakey, keccak123, martin, nameruse, oyc_109, pedr02b2, perseverancesuccess, rbserver, rotcivegaf, rvierdiiev, sakshamguruji, shark, simon135, subtle77, unforgiven, xiaoming90, yixxas
53.4851 USDC - $53.49
rewardTokens
, the owner of PirexRewards
will add to producerTokens[producerToken].rewardTokens
, looping through the array may result in OOG.userAccrue
in PirexRewards.sol
https://github.com/code-423n4/2022-11-redactedcartel/blob/03b71a8d395c02324cb9fdaf92401357da5b19d1/src/PirexRewards.sol#L281
userAccrue
generates UserAccrue
event, regardless whether or not there are any changes.
bracketing the updating logic and emit inside of the following condition
if (block.timestamp != u.lastUpdate || balance != u.lastBalance) { ... }
Similar issues exist in PxGmxReward.sol
for _globalAccue
and _userAccrue
https://github.com/code-423n4/2022-11-redactedcartel/blob/03b71a8d395c02324cb9fdaf92401357da5b19d1/src/vaults/PxGmxReward.sol#L49
https://github.com/code-423n4/2022-11-redactedcartel/blob/03b71a8d395c02324cb9fdaf92401357da5b19d1/src/vaults/PxGmxReward.sol#L68
ClaimRewards
may emit rewards values that are inconsistent with the actual rewards.This is due to the recalculation in place for rewardAmounts
.
ClaimRewards
should emit rewardAmounts
values in place the gmxBaseRewards, etc.
PxGmxReward
is not inheriting from ERC20, yet it is accessing ERC20 functions.AutoPxGlp
inherits from both PxGmxReward
and PirexERC4626
, which in turn from ERC20
. Therefore, things do work. However it is best practice to make code more explicity by inheriting from ERC20
.
withdraw
and redeem
functions in AutoPxGmx
can reuse the functions defined in PirexERC4626
by calling PirexERC4626.withdraw
and PirexERC4626.redeem
Fees can be calculated more accurately with rounding up as needed. For example,
feeAmount = (assets * fees[f]) / FEE_DENOMINATOR;
can be changed to
feeAmount = (assets * fees[f] + FEE_DENOMINATOR / 2) / FEE_DENOMINATOR;
#0 - c4-judge
2022-12-05T09:51:48Z
Picodes marked the issue as grade-b
🌟 Selected for report: gzeon
Also found by: 0xPanda, 0xSmartContract, B2, Deivitto, Diana, JohnSmith, PaludoX0, Rahoz, RaymondFam, ReyAdmirado, Rolezn, Schlagatron, Secureverse, Tomio, __141345__, adriro, ajtra, aphak5010, c3phas, chaduke, codeislight, cryptonue, datapunk, dharma09, halden, karanctf, keccak123, oyc_109, pavankv, sakshamguruji, saneryee, unforgiven
39.6537 USDC - $39.65
G1. previewWithdraw
and previewRedeem
in AutoPxGlp.sol
can be made external to save gas, since they are not called internally.
G2. harvest()
can be made more gas efficient if it keeps track of lastCallTime and returns immediately if lastCallTime is the same as current block.timeStamp
G3. totalAssets() and asset.balanceOf(address(this)) does the same thing, so create one local variable to save one SLOAD https://github.com/code-423n4/2022-11-redactedcartel/blob/03b71a8d395c02324cb9fdaf92401357da5b19d1/src/vaults/AutoPxGmx.sol#L288
#0 - c4-judge
2022-12-05T14:24:38Z
Picodes marked the issue as grade-b
#1 - drahrealm
2022-12-09T05:44:16Z
With the latest changes to the codebase (not reflected in the frozen codebase for audit here), some of the tips here are no longer beneficial, while others are considered minor relative to the added code complexity (aside from the fact that the target chains of the protocol is Arbitrum and Avalanche)
#2 - c4-sponsor
2022-12-09T05:44:23Z
drahrealm marked the issue as sponsor disputed