Yieldy contest - antonttc'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: 51/99

Findings: 2

Award: $81.29

🌟 Selected for report: 0

πŸš€ Solo Findings: 0

Low Severity

affiliateFee is not capped

there should be an upper bond of affiliateFee, to make sure even the owner cannot maliciously or accidentally set an affiliateFee that is too high.

Mitigation

function setAffiliateFee(uint256 _affiliateFee) external onlyOwner { require(affiliateFee < 2000); // < 20% affiliateFee = _affiliateFee; emit LogSetAffiliateFee(block.number, _affiliateFee); }

Gas Optimisation

1. Pack fee and isReserveEnabled in LiquidityReserveStorage.

fee can not be higher than base point units, and packing it with isReserveEnabled can save 1 SLAOD in functions like instantUnstake

Gas saving:

  • instantUnstakeReserve: avg. 344930 β‡’ 342961 (2000 gas)

2.Pack variables in StakingStorage

  • all time related value cannot realistically be higher than uint40.
  • and withdrawAmount / requestWithdrawAmount don’t realistically need full 256 bit slot, packing these 2 will save gas for _withdrawFromTokemak
uint40 public timeLeftToRequestWithdrawal; // time (in seconds) before TOKE cycle ends to request withdrawal
uint40 public warmUpPeriod; // amount of epochs to delay warmup vesting
uint40 public coolDownPeriod; // amount of epochs to delay cooldown vesting
uint40 public lastTokeCycleIndex; // last tokemak cycle index which requested withdrawals
uint40 public affiliateFee; // fee to send TOKE rewards

uint128 public requestWithdrawalAmount; // amount of staking tokens to request withdrawal once able to send
uint128 public withdrawalAmount; // amount of stakings tokens available for withdrawal

Gas saving

  • claimWithdraw: 152933 β‡’ 146400
  • instantUnstakeReserve: 344930 β‡’ 341710
  • unstake: 229140 β†’ 221856

3. Optimise enableLiquidityReserve by removing redundant check and avoid using state variables

2 tricks can be applied in this function:

  1. the following check is not important, because if the token balance of msg.sender is lower the MIN_LIQUIDITY, the token transfer won’t succeed
// These 2 lines are redundent
uint256 stakingTokenBalance = IERC20Upgradeable(stakingToken).balanceOf(
          msg.sender
);
require(
    stakingTokenBalance >= MINIMUM_LIQUIDITY,
    "Not enough staking tokens"
);

// ...
stakingContract = _stakingContract;

// only usin this is enough
IERC20Upgradeable(stakingToken).safeTransferFrom(
    msg.sender,
    address(this),
    MINIMUM_LIQUIDITY
);
  1. should use _stakingContract instead of stakingContract in the approve line, because reading function parameter is cheaper
IERC20Upgradeable(rewardToken).approve(
    _stakingContract, // instead of stakingContract which is state variable
    type(uint256).max
);

Gas saving:

enableLiquidityReserve: 187111 β‡’ 185874

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