Yieldy contest - Fabble's results

A protocol for gaining single side yields on various tokens.

General Information

Platform: Code4rena

Start Date: 21/06/2022

Pot Size: $50,000 USDC

Total HM: 31

Participants: 99

Period: 5 days

Judges: moose-code, JasoonS, denhampreen

Total Solo HM: 17

Id: 139

League: ETH

Yieldy

Findings Distribution

Researcher Performance

Rank: 74/99

Findings: 1

Award: $59.96

🌟 Selected for report: 0

🚀 Solo Findings: 0

Gas:

In LiquidityReserve.sol

  • in unstakeAllRewardTokens you can save stakingContract as a local variable to save a (warm) SLOAD.
  • in removeLiquidity you can avoid the require(_amount <= balanceOf(msg.sender), "Not enough lr tokens") as that check is already performed during _burn(msg.sender, _amount)
  • in _calculateReserveTokenValue you can declare a named returns variable as returns (uint256 convertedAmount) to save some gas for declaring another variable.
  • in enableLiquidityReserve you can save stakingToken as a local variable to save a storage read.

In BatchRequests.sol

  • in canBatchContracts you can add a local variable address currContract outside the for loop and in the loop do currContract = contracts[i] to save a (warm) SLOAD. Here you can also use a named returns statement like returns (Batch[] memory batch) to avoid declaring the local batch variable and save gas.
  • in sendWithdrawalRequests you can do the same for the currContract = contracts[i]

In Yieldy.sol

  • in initialize you can rewrite the linked code to this
decimal = _decimal; uint256 oneToken = 10**_decimal; WAD = oneToken; rebasingCreditsPerToken = oneToken; _setIndex(oneToken);

to save potentially 3 SLOADs

  • here in rebase you can use directly currentTotalSupply instead of _totalSupply
  • in _storeRebase you can save _totalSupply in a local var as it's read 2 times from storage
  • in _burn here you can use currentCredits directly instead of reading creditBalances[_address] from storage again

In Staking.sol:

  • In initialize you can always use function arguments instead of reading from the storage eg instead of if (CURVE_POOL != address(0)) { you should do if (_curvePool != address(0)) { so to save some gas
  • In _sendAffiliateFee you can read both affiliateFee and FEE_ADDRESS into local vars to save 2 SLOAD in total
  • In transferToke you can read FEE_ADDRESS into local var to save some gas
  • In _isClaimAvailable you can change info from memory to storage to avoid creating a copy in memory and read alwyas directly from storage
  • In _isClaimWithdrawAvailable you can change memory to storage for info like said before. Here you can also create a local variable for withdrawalAmount to avoid reading it twice.
  • In _requestWithdrawalFromTokemak you can also create a local variable for TOKE_POOL to avoid reading it twice.
  • In sendWithdrawalRequests you can read requestWithdrawalAmount into a local var. Same in
  • In stake you can read YIELDY_TOKEN into a local var to save potentially up to 3 SLOADs. Similarly also for warmUpPeriod.

General

  • in structs like Rebase, Claim and Epoch some values can be safely reduced in precision, so to pack values into 32 bytes. eg instead of this
struct Epoch { uint256 duration; // length of the epoch (in seconds) uint256 number; // epoch number (starting 1) uint256 timestamp; // epoch start time uint256 endTime; // time that current epoch ends on uint256 distribute; // amount of rewards to distribute this epoch }

you can do this

struct Epoch { uint32 duration; // length of the epoch (in seconds) uint32 number; // epoch number (starting 1) uint32 timestamp; // epoch start time uint32 endTime; // time that current epoch ends on uint128 distribute; // amount of rewards to distribute this epoch }

in this way you can use a single storage slot instead of 5 slots which is a pretty significant saving both for reads and writes.

require(_recipient.amount > 0, "Must enter valid amount");

to

error InvalidAmount(); if (_recipient.amount == 0) revert InvalidAmount();

same for all errors.

#0 - moose-code

2022-07-09T13:44:44Z

Good stuff

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter