Guess Meme Solidity

QuillAuditsFiles named in the report

Audit · firm’s term: audit report

QuillAudits reviewed Guess Meme Rust (Guess Meme Solidity) on 26 Feb 2025: 24 findings, 0 critical; 9 marked fixed, 15 open.

No open critical findings
Open the reportOpen Guess Meme Rust’s security record

Report hosted on quillaudits.com.

Trustblock does not review code.

Findings24

Statuses are the security firm’s own, from its report.

SeverityOpenAcknowledgedFixed
Critical000
High100
Medium502
Low907
Mediumprivate variables will lack privacy on the public blockchainFixed

Currently, the assumption that the name() and symbol() functions will return name and symbol only when the <strong>block.timestamp </strong>is greater than <strong>_reveal </strong>timestamp is incorrect as even private variables can be read in various ways e.g. By checking the previous token creation transaction and by fetching the storage slot value, etc.<br> <br>That’s why it’s important to verify and change the logic to avoid this issue.

MediumUnable to complete the bonding curveFixed

The withdraw() can be called when the bonding curve is reached, i.e., when the <strong>realTokenReserves </strong>is <strong>0</strong>. But because while buying, it checks that the user should buy less than or equal to <strong>maxSupplyPercentage</strong> percent, there are chances that <strong>realTokenReserves </strong>will never reach to <strong>0</strong>.<br> <br>let's say the <strong>maxSupplyPercentage </strong>is 80, which means the user can buy <strong>80%</strong> of <strong>realTokenReserves </strong>amount in a single transaction. And the requirement to set <strong>isCompleted </strong>to true is when <a href="https://github.com/sardar-khan/guess-meme-contracts/blob/main/ethereum/eth_guessmeme.sol#L739-L741" target="_blank">realTokenReserves == 0</a>.<br> <br>So if every time the user can only buy 80% of the remaining <strong>realTokenReserves</strong>,<br>while buying, reaching <strong>realTokenReserves </strong>to 0 is not always possible. while it can reach close to 0 (e.g. 1) but not 0. its because e.g. the <strong>realTokenReserves </strong>reaches 1 but the 80% of 1 would be 0 in solidity, and that's why it can't be even specified in the <strong>buyTokens()</strong> function call.

LowAdd the max limit for changeFeeBasisPoints()Fixed

Currently, 100% of the fee can be set through feeBasisPoints using <strong>changeFeeBasisPoints() </strong>function. It should be capped to a specific number to improve users' transparency so that the fee won't exceed a specific percentage.

LowAssumption about withdraw() fee subtraction logicFixed

In <strong>withdraw()</strong> on <strong>L779 </strong>while subtracting <strong>feeTokens </strong>amount from <strong>tokensToTransfer</strong>, it's assumed that it will be always lesser than <strong>tokensToTransfer </strong>so there won't be any arithmetic errors while subtraction.<br> <br>It is assumed that <strong>feeTokens </strong>would be always lesser than <strong>tokensToTransfer </strong>because <strong>feeTokens </strong>is 1% of <strong>_totalSupply</strong>. Given that <strong>realTokenReserves </strong>is  <strong>793100000 *10**18 </strong>and <strong>_totalSupply </strong>would be <strong>1000000000e18</strong>. when the <strong>withdraw()</strong> is executed the <strong>realTokenReserves </strong>will have already reached 0. That means <strong>1000000000e18 </strong>- <strong>793100000e18 </strong>= <strong>206900000e18 </strong>is the current remaining amount that the contract holds. which is around <strong>20.69% </strong>of the <strong>1000000000e18</strong>.<br> <br>So on <strong>L774 </strong>when calculating <strong>1% </strong>of <strong>1000000000e18 </strong>it would be <strong>10000000e18 </strong>which is less than the remaining <strong>20.69% </strong>(<strong>206900000e18</strong>). Hence there should not be any underflow error in the <strong>tokensToTransfer - feeTokens subtraction </strong>on <a href="https://github.com/sardar-khan/guess-meme-contracts/blob/main/ethereum/eth_guessmeme.sol#L779C45-L779C73" target="_blank"><strong>L779</strong></a>.<br> <br>Note: Because depending on the <strong>_totalSupply </strong>(if it’s different than 1 billion)<strong> </strong>entered, while withdrawing the remaining amount in the contract (<strong>tokensToTransfer</strong>) will vary. if the <strong>tokensToTransfer </strong>is less than <strong>feeTokens</strong>, it can create the arithmetic error.

LowChange the comment to match the feeBasisPoints valueFixed

<strong>feeBasisPoints </strong>is set to 100. and the comment mentions <strong>0.01 %.</strong><br> <br>The fee calculation works like this:<br><strong>(ethToBuy * feeBasisPoints) / 10_000;</strong><br>Lets say <strong>ethToBuy</strong>=1e18 and <strong>feeBasisPoints </strong>= 100, then:<br>= (1e18 * 100) / 10_000<br>= 100000000000000000000 / 10_000<br>= 10000000000000000 ( it is 1 % of the 1e18 and not 0.01 % of 1e18( ethToBuy) )

LowChange the variable name to avoid confusionFixed

variable name <strong>initialRealEthReserves </strong>should be changed to <strong>initialRealTokenReserves</strong>. <strong>initialRealEthReserves </strong>name is not correct as the real eth reserve would be 0 initially.

LowFloating pragmaFixed

Multiple contracts are using version (^0.8.0 and ^0.8.26) with floating pragma instead of locking to a specific version. floating pragmas allow the contract to be compiled with any version greater than or equal to the specified version. If the contract wasn’t thoroughly tested with that version, this can introduce possible bugs.<br>Additionally, Only one solidity version can be used for the contract.

LowHardcode the totalsupplyFixed

As discussed internally, the <strong>_totalSupply</strong> will be 1 billion for every token sale that is created. Still, it’s good practice to set the hardcoded value to the <strong>_totalSupply </strong>to avoid any unexpected results as mentioned in other issues.

LowsellQuote rounds up the resultFixed

The <strong>sellQuote() </strong>returns the ETH amount that the users will receive for selling tokens. This function rounds up the ETH to receive. <br> <br>So if the user returns the same bought token amount, the formula will return a slightly higher ETH value with 1 wei, as compared to what was required while buying.<br> <br><strong>sellQuote()</strong> should never round up because in sell, the eth returned is the eth amount users will receive from the protocol.

Contracts in scope

No deployed address is recorded for this audit.

The report names a repository or files. Open the report to see its scope.

Repository and files the report names (3)

  • eth_guessmeme.sol
  • guess_meme_latest.sol
  • ts/blob/main/ethereum/guess_meme_latest.sol

Part of Guess Meme Rust’s security record

Guess Meme Rust
Audits2 audits by 1 firmLast audit Feb 2025, by QuillAudits.
Critical findingsNo open critical findingsAcross 2 reports.
Open Guess Meme Rust’s security record

Security firm

QuillAudits

350 projects reviewed · 459 reports · latest Apr 2025

See QuillAudits’s audits

Something wrong on this page? A missing report, a wrong date, a finding that was fixed since. Tell us and we check it against its source.

Tell us