Skip to content

Instantly share code, notes, and snippets.

@chhajershrenik
Created April 22, 2023 15:40
Show Gist options
  • Save chhajershrenik/0c1c678c62a30f51d1786b0d347c5680 to your computer and use it in GitHub Desktop.
Save chhajershrenik/0c1c678c62a30f51d1786b0d347c5680 to your computer and use it in GitHub Desktop.
Binance Smart Chain (BSC) PandAI Earn Contracts Security Re-Audit Report

Binance Smart Chain (BSC) PandAI Earn Contracts Security Re-Audit Report.

1. Summary

PandAI Earn smart contracts security audit report performed by chhajershrenik.

2. In scope

Commit: bce9e71647a72bdf0704cb09787c0baf267e082f

3. Findings

In total, 2 issues were reported, including:

  • 1 medium severity issue.

  • 1 low severity issue.

In total, 6 notes were reported, including:

  • 1 note.

  • 5 owner privileges.

3.1. PandAi/USDT price manipulation is possible by an arbitrary user by trading PandAi/USDT tokens into the liquidity pool address

Severity: medium

Description

An arbitrary user can inflate the price of PandAi/USDT value by staking high volume in the lpaddress and deflate the value by unstaking the previous deposit. The contract deployed at lpaddress is not in the scope of this audit.

Code Snippet

3.2. Incorrect comparision in function canClaim()

Severity: low

Description

For an uninitialized ApprovalLevel of a wallet, the wallet must be allowed to claim $1000 as a daily limit. The statement incorrectly checks the claimUsdt value to DAILY_CLAIM_LIMIT.

Code Snippet

Recommendation

Consider updating the following statement in the function canClaim()

claimUsdt / (10 ** usdtToken.decimals()) < DAILY_CLAIM_LIMIT

to

claimUsdt / (10 ** usdtToken.decimals()) <= DAILY_CLAIM_LIMIT

3.3. Owner Privileges

Severity: owner privileges

Description

  1. Contract PandAIEarn inherits the traits of OpenZeppelin AccessControl contract allowing admin to manage admin's, the role could be renounced leading to locking out of access to critical functions of the contract.
  2. Functions pause() and unpause allows the admin to disable or enable the ability for the user's deposit USDT tokens or claim rewards respectively. But still allows users to withdraw requests and can withdraw deposit USDT tokens from the contract.
  3. Function setLpAddress() allows the admin to change the liquidity pool address to any wallet, the value of PandAi tokens would be affected which is computed using the function getPandaiWorthOf() based on the amount of USDT tokens and PandAi tokens available in newLpAddress wallet.
  4. Function withdrawTreasury() allows the admin to withdraw USDT tokens from the contract to the admin address.
  5. Function setUserApprovalLevel() allows admin to change the claim status of any wallet address to NotApproved, Approved, and Forbidden limiting the user's ability to withdraw or restrict a user from withdrawing USDT tokens deposited in the contract based on the approval status. Any wallet with an uninitialized approval level cannot claim rewards if the daily reward is greater than $1000.

Recommendation

Since the owner has unlimited rights to do everything, the ownership must be transferred to a multi-sig contract.

3.4. Follow good coding practice

Severity: note

Description

  1. Unorganized and non-standardized docstrings

The contracts in the code base contain unorganized and non-standardized docstring does not explain the contract's state and functionalities in detail. This hinders reviewers’ understanding of the code’s intention, which is fundamental to correctly assess not only security but also correctness. Additionally, detailed docstrings improve readability and ease maintenance. They should explicitly explain the purpose or intention of the functions, the scenarios under which they can fail, the roles allowed to call them, the values returned, and the events emitted.

Consider thoroughly documenting all functions (and their parameters) that are part of the contracts’ public API. Functions implementing sensitive functionality, even if not public, should be documented as well. When writing docstrings, consider following the Ethereum Natural Specification Format (NatSpec).

4. Security practices

  • Open-source contact.
  • The contract should pass a bug bounty after the completion of the security audit.
  • Public testing.
  • Automated anomaly detection systems. - NOT IMPLEMENTED. A simple anomaly detection algorithm is recommended to be implemented to detect behavior that is atypical compared to normal for this contract. For instance, the contract must halt deposits in case a large amount is withdrawn in a short period until the owner or the community of the contract approves further operations.
  • Multisig owner account.
  • Standard ERC20-related issues. - NOT IMPLEMENTED. It is known that every contract can potentially receive an unintended ERC20-token deposit without the ability to reject it even if the contract is not intended to receive or hold tokens. As a result, it is recommended to implement a function that will allow extracting any arbitrary number of tokens from the contract.
  • Crosschain address collisions. ETH, ETC, CLO, etc. It is possible that a transaction can be sent to the address of your contract at another chain (as a result of a user mistake or some software fault). It is recommended that you deploy a "mock contract" that would allow you to withdraw any tokens from that address or prevent any funds deposits. Note that you can reject transactions of native tokens deposited, but you can not reject the deposits of ERC20 tokens. You can use this source code as a mock contract: extractor contract source code. The address of a new contract deployed using CREATE (0xf0) opcode is assigned following this scheme keccak256(rlp([sender, nonce])). Therefore you need to use the same address that was originally used at the main chain to deploy the mock contract at a transaction with the nonce that matches that on the original chain. Example: If you have deployed your main contract with address 0x010101 at your 2021th transaction then you need to increase your nonce of 0x010101 address to 2020 at the chain where your mock contract will be deployed. Then you can deploy your mock contract with your 2021th transaction, and it will receive the same address as your mainnet contract.
@yuriy77k
Copy link

3.1. PandAi/USDT price manipulation is possible by an arbitrary user by trading PandAi/USDT tokens into the liquidity pool address

Price manipulation performed by regular trading is not considered a smart contract security issue. An attacker has a risk of losing his money when another trader performs the opposite trade. Only flash loan price manipulation allows an attacker to be 100% safe, but it was fixed in the contract.

@chhajershrenik
Copy link
Author

3.1. PandAi/USDT price manipulation is possible by an arbitrary user by trading PandAi/USDT tokens into the liquidity pool address

Price manipulation performed by regular trading is not considered a smart contract security issue. An attacker has a risk of losing his money when another trader performs the opposite trade. Only flash loan price manipulation allows an attacker to be 100% safe, but it was fixed in the contract.

Got it, thank you!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment