Platform: Code4rena
Start Date: 26/05/2022
Pot Size: $75,000 USDT
Total HM: 31
Participants: 71
Period: 7 days
Judge: GalloDaSballo
Total Solo HM: 18
Id: 126
League: ETH
Rank: 39/71
Findings: 2
Award: $168.24
π Selected for report: 0
π Solo Findings: 0
π Selected for report: IllIllI
Also found by: 0x1f8b, 0x29A, 0xDjango, 0xNazgul, 0xf15ers, BouSalman, Chom, Deivitto, Dravee, ElKu, FSchmoede, Funen, GimelSec, Hawkeye, MiloTruck, Picodes, SecureZeroX, SmartSek, TerrierLover, WatchPug, _Adam, asutorufos, berndartmueller, c3phas, catchup, cccz, cogitoergosumsw, cryptphi, csanuragjain, delfin454000, dipp, ellahi, gzeon, hansfriese, horsefacts, hyh, kirk-baird, minhquanym, oyc_109, pauliax, reassor, robee, sashik_eth, shenwilly, simon135, sorrynotsorry, sseefried, unforgiven, xiaoming90, z3s
99.9237 USDT - $99.92
In VeAssetDepositor.sol#L117-L120, the condition to mint the additional rewards tokens to the user is if (incentiveVeAsset > 0)
. However, the incentiveVeAsset
variable is only updated to zero after an external call to the ITokenMinter
contract. This lacks the Checks Effects and Interactions safety pattern. In the event that the wrong minter contract has been initialised, an attacker could potentially drain all the additional reward tokens via a reentrancy attack.
Be sure to follow the Checks Effects and Interactions safety pattern and update the incentiveVeAsset = 0
before minting the token for the user. Alternatively, the developers can also add the nonReentrant()
modifier from OpenZeppelin to prevent any sort of potential reentrancy attacks.
#0 - jetbrain10
2022-06-15T15:38:29Z
We will fix it
#1 - GalloDaSballo
2022-07-20T00:13:31Z
Agree that the code is not CEI compliant, disagree with the Medium Severity in lack of:
minter
Believe QA to be a more appropriate severity
π Selected for report: IllIllI
Also found by: 0x1f8b, 0x29A, 0xKitsune, 0xNazgul, 0xf15ers, 0xkatana, Cityscape, Dravee, ElKu, FSchmoede, Funen, GalloDaSballo, Hawkeye, Kaiziron, MiloTruck, Randyyy, RoiEvenHaim, Ruhum, SecureZeroX, SmartSek, TerrierLover, TomJ, Tomio, WatchPug, Waze, _Adam, asutorufos, c3phas, catchup, cogitoergosumsw, delfin454000, ellahi, fatherOfBlocks, gzeon, hansfriese, horsefacts, jonatascm, minhquanym, oyc_109, pauliax, reassor, robee, sach1r0, saian, sashik_eth, simon135, z3s
68.3171 USDT - $68.32
Reducing from public to private or internal can save gas when a constant isnβt used outside of its contract. I suggest changing the visibility from public to internal or private here:
uint256 public constant duration = 7 days;
- BaseRewardPool.sol#L57
uint256 public constant newRewardRatio = 830;
- BaseRewardPool.sol#L73
uint256 public constant MaxFees = 2000;
- Booster.sol#L33
uint256 public constant FEE_DENOMINATOR = 10000;
- Booster.sol#L34
!= 0 costs less gas compared to > 0 for unsigned integers in require statements with the optimizer enabled (6 gas) with optimizer switched on, less gas is used.
Use !=
instead for unsigned integer comparisons
For example,
BaseRewardPool.sol:173: require(_amount > 0, "RewardPool : Cannot stake 0");
Some variables can be set to immutable
type since they will only ever be set once. This can help to save gas.
address public stakerLockRewards;
- Booster.sol#L48
address public stakerLockRewards;
- Booster.sol#L53
uint256 public pid;
- ExtraRewardStashV1.sol#L23
address public operator
- ExtraRewardStashV1.sol#L24
uint256 public pid
- ExtraRewardStashV1.sol#L23
address public staker
- ExtraRewardStashV1.sol#L25
address public gauge;
- ExtraRewardStashV1.sol#L26
address public rewardFactory;
- ExtraRewardStashV1.sol#L27
address public owner = msg.sender
- Migrations.sol#L5
string private _name
- VE3DLocker.sol#L109
string private _symbol
- VE3DLocker.sol#L110
string public name;
- VoterProxy.sol#L30
Some gas can be saved when less variables are assigned. In the examples below, the variables declared are not reused in other parts of the code.
Can be replaced with
//withdraw from gauge try IStaker(staker).withdrawAll(pool.lptoken, pool.gauge) { pool.shutdown = true; } catch {}
Booster.sol:53: address token = pool.lptoken;
- Booster.sol#L337
Booster.sol:53: address gauge = pool.gauge;
- Booster.sol#L337
#0 - GalloDaSballo
2022-07-14T01:53:31Z
25000 from the immutables rest is minor
#1 - GalloDaSballo
2022-07-28T20:30:44Z
TODO: Remove Stash Points
#2 - GalloDaSballo
2022-07-28T22:31:49Z
Removing Out of Scope Contracts:
7 * 2100
Gas saved in scope: 10300