Wenwin contest - seeu's results

The next generation of chance-based gaming.

General Information

Platform: Code4rena

Start Date: 06/03/2023

Pot Size: $36,500 USDC

Total HM: 8

Participants: 93

Period: 3 days

Judge: cccz

Total Solo HM: 3

Id: 218

League: ETH

Wenwin

Findings Distribution

Researcher Performance

Rank: 67/93

Findings: 1

Award: $21.70

QA:
grade-b

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

21.7018 USDC - $21.70

Labels

bug
grade-b
QA (Quality Assurance)
sponsor confirmed
Q-05

External Links

Low issues

IDIssueContextsInstances
L-01Outdated Compiler Version22
L-02Compiler version Pragma is non-specific22
L-03Use _safeMint instead of _mint34
L-04Use require instead of assert22
L-05decimals() is not part of ERC20 standard and it may fail13
L-06Timestamp dependency411
Total issuesTotal contextsTotal instances
61424

[L-01] Outdated Compiler Version

Description

Using an older compiler version might be risky, especially if the version in question has faults and problems that have been made public.

Findings

References

[L-02] Compiler version Pragma is non-specific

Description

For non-library contracts, floating pragmas may be a security risk for application implementations, since a known vulnerable compiler version may accidentally be selected or security tools might fallback to an older compiler version ending up checking a different EVM compilation that is ultimately deployed on the blockchain.

Findings

References

[L-03] Use _safeMint instead of _mint

Description

In favor of _safeMint(), which guarantees that the receiver is either an EOA or implements IERC721Receiver, _mint() is deprecated.

Findings

References

[L-04] Use require instead of assert

Description

It is reccomended to use require instead of assert since the latest, when false, uses up all the remaining gas and reverts all the changes made.

Findings

References

[L-05] decimals() is not part of ERC20 standard and it may fail

Description

Since decimals() is not a part of the official ERC20 standard, it could not work for some tokens.

Findings

  • src/LotterySetup.sol
    ::79 =>         uint256 tokenUnit = 10 ** IERC20Metadata(address(lotterySetupParams.token)).decimals();
    ::128 =>             return extracted * (10 ** (IERC20Metadata(address(rewardToken)).decimals() - 1));
    ::168 =>         uint256 divisor = 10 ** (IERC20Metadata(address(rewardToken)).decimals() - 1);

References

[L-06] Timestamp dependency

Description

The timestamp of a block is provided by the miner who mined the block. As a result, the timestamp is not guaranteed to be accurate or to be the same across different nodes in the network. In particular, an attacker can potentially mine a block with a timestamp that is favorable to them, known as "selective packing".

For example, an attacker could mine a block with a timestamp that is slightly in the future, allowing them to bypass a time-based restriction in a smart contract that relies on block.timestamp. This could potentially allow the attacker to execute a malicious action that would otherwise be blocked by the restriction.

It is reccomended to, instead, use an alternative timestamp source, such as an oracle, that is not susceptible to manipulation by a miner.

Findings

  • src/Lottery.sol
    ::135 =>         if (block.timestamp < drawScheduledAt(currentDraw)) {
    ::164 =>             if (block.timestamp <= ticketRegistrationDeadline(ticketInfo.drawId + LotteryMath.DRAWS_PER_YEAR)) {
  • src/LotterySetup.sol
    ::74 =>         if (initialPotDeadline < (block.timestamp + lotterySetupParams.drawSchedule.drawPeriod)) {
    ::114 =>         if (block.timestamp > ticketRegistrationDeadline(drawId)) {
    ::137 =>         if (block.timestamp <= initialPotDeadline) {
  • src/RNSourceController.sol
    ::64 =>         if (block.timestamp - lastRequestTimestamp <= maxRequestDelay) {
    ::70 =>             maxFailedAttemptsReachedAt = block.timestamp;
    ::94 =>         bool notEnoughTimeReachingMaxFailedAttempts = block.timestamp < maxFailedAttemptsReachedAt + maxRequestDelay;
    ::107 =>         lastRequestTimestamp = block.timestamp;
  • src/staking/StakedTokenLock.sol
    ::26 =>         if (block.timestamp > depositDeadline) {
    ::39 =>         if (block.timestamp > depositDeadline && block.timestamp < depositDeadline + lockDuration) {

References

Non-Critical issues

IDIssueContextsInstances
NC-01Unnamed return parameters11
NC-02Pragma Version 0.8.17 too recent to be trusted11
NC-03For modern and more readable code; update import usages2053
Total issuesTotal contextsTotal instances
32255

[NC-01] Unnamed return parameters

Description

To increase explicitness and readability, take into account introducing and utilizing named return parameters.

Findings

References

[NC-02] Pragma Version 0.8.17 too recent to be trusted

Description

In recert versions, unexpected problems might be reported. Use a more robust, non-legacy version like 0.8.10.

Findings

References

[NC-03] For modern and more readable code; update import usages

Description

A less obvious way that solidity code is clearer is the struct Point. Prior to now, we imported it via global import, but we didn't use it. The Point struct contaminated the source code with an extra object that was not needed and that we were not utilizing.

To be sure to only import what you need, use specific imports using curly brackets.

Findings

  • src/Lottery.sol
    ::5 => import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
    ::6 => import "@openzeppelin/contracts/utils/math/Math.sol";
    ::7 => import "src/ReferralSystem.sol";
    ::8 => import "src/RNSourceController.sol";
    ::9 => import "src/staking/Staking.sol";
    ::10 => import "src/LotterySetup.sol";
    ::11 => import "src/TicketUtils.sol";
  • src/LotteryMath.sol
    ::5 => import "src/interfaces/ILottery.sol";
    ::6 => import "src/PercentageMath.sol";
  • src/LotterySetup.sol
    ::5 => import "@openzeppelin/contracts/utils/math/Math.sol";
    ::6 => import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
    ::7 => import "src/PercentageMath.sol";
    ::8 => import "src/LotteryToken.sol";
    ::9 => import "src/interfaces/ILotterySetup.sol";
    ::10 => import "src/Ticket.sol";
  • src/LotteryToken.sol
    ::5 => import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
    ::6 => import "src/interfaces/ILotteryToken.sol";
    ::7 => import "src/LotteryMath.sol";
  • src/RNSourceBase.sol
    ::5 => import "src/interfaces/IRNSource.sol";
  • src/RNSourceController.sol
    ::5 => import "@openzeppelin/contracts/access/Ownable2Step.sol";
    ::6 => import "src/interfaces/IRNSource.sol";
    ::7 => import "src/interfaces/IRNSourceController.sol";
  • src/ReferralSystem.sol
    ::5 => import "@openzeppelin/contracts/utils/math/Math.sol";
    ::6 => import "src/interfaces/IReferralSystem.sol";
    ::7 => import "src/PercentageMath.sol";
  • src/Ticket.sol
    ::5 => import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
    ::6 => import "src/interfaces/ITicket.sol";
  • src/VRFv2RNSource.sol
    ::5 => import "@chainlink/contracts/src/v0.8/VRFV2WrapperConsumerBase.sol";
    ::6 => import "src/interfaces/IVRFv2RNSource.sol";
    ::7 => import "src/RNSourceBase.sol";
  • src/interfaces/ILottery.sol
    ::5 => import "src/interfaces/ILotterySetup.sol";
    ::6 => import "src/interfaces/IRNSourceController.sol";
    ::7 => import "src/interfaces/ITicket.sol";
    ::8 => import "src/interfaces/IReferralSystem.sol";
  • src/interfaces/ILotterySetup.sol
    ::5 => import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
    ::6 => import "src/interfaces/ITicket.sol";
  • src/interfaces/ILotteryToken.sol
    ::5 => import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
  • interfaces/IRNSourceController.sol
    ::5 => import "@openzeppelin/contracts/access/Ownable2Step.sol";
    ::6 => import "src/interfaces/IRNSource.sol";
  • src/interfaces/IReferralSystem.sol
    ::5 => import "src/interfaces/ILotteryToken.sol";
  • src/interfaces/ITicket.sol
    ::5 => import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
  • src/interfaces/IVRFv2RNSource.sol
    ::5 => import "src/interfaces/IRNSource.sol";
  • src/staking/StakedTokenLock.sol
    ::5 => import "@openzeppelin/contracts/access/Ownable2Step.sol";
    ::6 => import "src/staking/interfaces/IStakedTokenLock.sol";
    ::7 => import "src/staking/interfaces/IStaking.sol";
  • src/staking/Staking.sol
    ::5 => import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
    ::6 => import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
    ::7 => import "src/interfaces/ILottery.sol";
    ::8 => import "src/LotteryMath.sol";
    ::9 => import "src/staking/interfaces/IStaking.sol";
  • src/staking/interfaces/IStakedTokenLock.sol
    ::5 => import "src/staking/interfaces/IStaking.sol";
  • staking/interfaces/IStaking.sol
    ::5 => import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
    ::6 => import "src/interfaces/ILottery.sol";

References

#0 - thereksfour

2023-03-12T07:20:59Z

2 L 4 INFO 3NC

#1 - c4-judge

2023-03-12T07:21:05Z

thereksfour marked the issue as grade-b

#2 - c4-sponsor

2023-03-14T09:55:30Z

0xluckydev marked the issue as sponsor confirmed

#3 - 0xluckydev

2023-03-14T09:56:03Z

Low priority ERC721 safe mint should be ignored like for the rest of issues

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