Buy The Dip x Solid Group : Audit Results

Solidgroup
6 min readJun 13, 2021

Auditing Process

Solid Group’s auditing process goes in-depth and covers a wide range of token code characteristics. The main things the audit checks for are vulnerabilities and imminent risks to the safety and security of the code, Solid Group does an extensive auditing process intending to help their customers increase their code quality while reducing the high level of risk presented by cryptographic tokens and blockchain technology.

Contract

dipmaster | wojak |bogdf | woj |bog

✅ BEP-20’s Conformance

✅ No external mint function

✅ No volatile code

Audit Findings

PCSHandler.sol

  • Issue 𝟏| Best Practice|🟢 Informational | ✅ Fixed

Description

The function removeLiquidity is not used.

Recommendation

Our recommendation is to remove this function to save on gas fees and storage.

ERC20.sol

  • Issue 𝟏| Gas Optimization|🟢 Informational |🔍 _transfer() | ✅ Fixed

Description

Calling external functions multiple times airdropContract.masterAddress(), instead of reusing the return value of one external call in order to save gas fees.

Airdrop

Issue #1 | Logical Issue | 🔴 High | 🔍 subEligible() | ✅ Fixed

Description

This function is being called from the token contract. Therefore, onlyPcs modifier will always be false, which means subEligible function will always fail.

Issue #2 | Logical Issue | 🟢 Informational |🔍 startRound | ✅ Fixed

Description

It is preferable to use the last round counter instead of manually specifying it as a param.

BuyTheDip.sol

Issue #1 | Logical Issue | 🔴 High | 🔍 claimAirdrop() | ✅ Fixed

Description

msg.sender could get the tokensOwed twice — One time from the transfer itself, and the second time by calling transferFrom after giving msg.sender allowance to transfer tokensOwed on behalf of the contract.

approve(msg.sender, tokensOwed);            
_lowLevelTransfer(_user, tokensOwed);

Recommendation

Remove the call to the approve function.

Issue #2 | Best Practice |🟢 Informational | 🔍 mint() | ✅ Fixed

Description

Consider removing the public mint function if it’s only used once.

Issue #3 | Owner Capabilities |🟢 Informational | setMaster() | ✅ Fixed

Description

The owner can change DipMaster contract address.

Recommendation

Remove this function, or prohibit it from being executed more than once.

DipMaster.sol

Issue #2 | Volutile Code | 🟡 Low | 🔍 startRound() | ✅ Fixed

Description

If this random number’s goal is to hide the final endRoundTime from attackers, it won’t work since private variables (randomTimeFrame) are publicly visible. A malicious actor could determine the end round and manipulate the price.

Our Recommendation

Consider using TWAP.

Issue #3 | Unused Code/Gas Optimization | 🟢 Informational | ✅ Fixed

Description

hasWon variable is unused.

roundOver modifier is unused.

modifier roundOver() {
require(hasWon, "Round is not over yet");
_;
}

Issue #4 | Centralization | 🟢 Informational | 🔍 startRound() | ✅ Fixed

Description

startRound can only be called by the owner. This means it will be much more difficult to renounce ownership in the future or apply a governance contract that would be able to call startRound as part of a governance decision.

function startRound(uint _timeInMins) public override onlyOwner

Recommendation

Our recommendation is to work according to Role-Based Access Control.

✅ The team fixed this issue the only address which could start the round is the DipMaster contract:

function startRound() external onlyMaster {

Issue #5| Logical Issue | 🔴 High | 🔍 setWinner() | ✅ Fixed

Description

If the difference between wojakStartPrice and currentWojakPrice (=wojakDifference) is less than wojakStartPrice the division (decrease / wojakStartPrice) or (increase / wojakStartPrice) will be zero because solidity performs integer division.

For example:

if the currentWojakPrice = 110 and wojakStartPrice = 100

uint increase = currentWojakPrice — wojakStartPrice = 110–100 = 10

and wojakDifference = (decrease / wojakStartPrice) * 100; will be zero because 10/100 = 0

if(currentWojakPrice < wojakStartPrice){
wojakGain = false;
uint decrease = wojakStartPrice - currentWojakPrice;
wojakDifference = (decrease / wojakStartPrice) * 100;
} else {
wojakGain = true;
uint increase = currentWojakPrice - wojakStartPrice;
wojakDifference = (increase / wojakStartPrice) * 100;
}

if(currentBogPrice < bogStartPrice){
bogGain = false;
uint decrease = bogStartPrice - currentBogPrice;
bogDifference = (decrease / bogStartPrice) * 100;
} else {
bogGain = true;
uint increase = currentBogPrice - bogStartPrice;
bogDifference = (increase / bogStartPrice) * 100;
}

Recommendation

Make sure the difference (decrease/increase) will be an order of magnitude greater than bogStartPrice and wojakStartPrice

Issue #7 | Logical Issue |🔴 High |🔍 claimAirdrop() | ✅ Fixed

Description

claimAirdrop function can be called by anyone.

function claimAirdrop(address _airdropAddress, address _user, uint _round) public override

This function calls BuyTheDip (i.e the token) claimAirdrop function.

BuyTheDip(_airdropAddress).claimAirdrop(_user, _round);

If someone calls this function in the middle of the round,

airdropInfo[_round].hasLost will be false because the default value for bool is false, Therefore, the if statement

if(!airdropInfo[_round].hasLost)

will be True for both of the tokens making the claiming available in the middle of the round.

Recommendation

require(_round <= lastRound, “You cannot claim an airdrop that hasn’t happened yet”);

Fixed

Airdrop can be claimed only for rounds that were completed and not in the middle of the round. Future rounds will also not work since don’t have any airdrop token allocation.

Issue #8 | Owner Capabilities |🟢 Informational | setAddresses()| ✅ Fixed

Classification

The owner can change the addresses DipMaster communicates with by calling

function setAddresses(address _wojak, address _bog, address _wojakLpPair, address _bogLpPair) public onlyOwner

Recommendation

Remove this function, or prohibit it from being executed than once.

  • The scope of the audit would treat the third-party implementation at pancakeRouter as a black box and assume its functional correctness. Solid Group Doesn’t cover integration with third-party services (Such as PancakeSwap). The team should test this on their own in test nets or any other mechanism.
  • As with many scheduled price changes, buy the dip is vulnerable to a front running attack — an attacker can send a buy tx right before a winner is announced as this information is publicly available ahead of time.

Summary

The team fixed all the issues we found. The code is vulnerable to a front running attack — an attacker can send a buy tx right before a winner is announced as this information is publicly available ahead of time.

About Buy The Dip

“BuyTheDip is a pumpetition of two tokens: WOJAK & BOGDF. The idea is to create a competition between the two tokens, to see which can pump the hardest within a given timeframe, which resets, and continues the cycle for both tokens. In order to incentivize pumping one over the other, 10% of the liquidity pool of the losing token will be pulled(automatically) in order to buyback the other token, this creates buying pressure. A large amount has also been allocated for airdrops, where 1% of the total airdrop pool will be distributed amongst holders of the losing token.”

🌏 Website |🗣Telegram |📣Twitter |🅜 GitHub

About Solid Group

Solid Group is a blockchain consulting and auditing service provider, founded by 3 cybersecurity experts with a passion for thinking out of the box, learning, and sharing knowledge. Every project goes through a meticulous process and is viewed by at least two partners, thereby achieving a high level of credibility and professionalism. Our group is partnered with multiple organizations and launchpads that have a combined market cap of over 400 million USD.

📣 Telegram| 🗣Telegram discussion group |🐦 Twitter |🛡 Contact for audit | 🤖 Audit Checker bot

Disclaimer

SolidGroup reports are not, nor should be considered, an “endorsement” or “disapproval” of any particular project or team. These reports are not, nor should be considered, an indication of the economics or value of any “product” or “asset” created by any team. Solid Group does not cover testing or auditing the integration with external contracts or services (such as Unicrypt, Uniswap, PancakeSwap, etc’…)

SolidGroup Audits do not provide any warranty or guarantee regarding the absolute bug-free nature of the technology analyzed, nor do they provide an indication of the technology proprietors. SolidGroup Audits should not be used in any way to make decisions around investment or involvement with any particular project. These reports in no way provide investment advice, nor should be leveraged as investment advice of any sort. SolidGroup Reports represent an extensive auditing process intending to help our customers increase the quality of their code while reducing the high level of risk presented by cryptographic tokens and blockchain technology. Blockchain technology and cryptographic assets present a high level of ongoing risk. SolidGroup’s position is that each company and individual are responsible for their own due diligence and continuous security. SolidGroup in no way claims any guarantee of security or functionality of the technology we agree to analyze.

--

--

Solidgroup

We are a group 3 software developers with combined experience of over 15years in various fields such as Software design, Operating systems, and solidity.