Chainpals Transaction Audit Report

Table Of Content



BlockApex (Auditor) was contracted by Chainpals (Client) for the purpose of conducting a Smart Contract Audit/Code Review. This document presents the findings of our analysis which took place on  15th June 2022. 

Name: ChainpalsTransaction
Auditor: Kaif Ahmed | Mohammad Memon
Platform: Ethereum/Solidity/BCS
Type of review: Manual Code Review | Automated Code Review
Methods: Architecture Review, Functional Testing, Computer-Aided Verification, Manual Review
Git repository: -
White paper/ Documentation:
Document log:
Initial Audit: 16th June 2022
Final Audit: 22 June 2022


The git-repository shared was checked for common code violations along with vulnerability-specific probing to detect major issues/vulnerabilities. Some specific checks are as follows:

Code reviewFunctional review
Reentrancy Unchecked external callBusiness Logics Review
Ownership TakeoverERC20 API violationFunctionality Checks
Timestamp DependenceUnchecked mathAccess Control & Authorization
Gas Limit and LoopsUnsafe type inferenceEscrow manipulation
DoS with (Unexpected) ThrowImplicit visibility levelToken Supply manipulation
DoS with Block Gas LimitDeployment ConsistencyAsset’s integrity
Transaction-Ordering DependenceRepository ConsistencyUser Balances manipulation
Style guide violationData ConsistencyKill-Switch Mechanism
Costly LoopOperation Trails & Event Generation

Project Overview

Chainpals transaction contract is responsible for handling the multi-phased transactions that take place between a buyer and a seller, each overlooked by escrow managers to make sure everything goes smoothly.

System Architecture

The trio of Chainpals contracts form a system that allows end-users to meet, setup transaction details (allowing payments in any BEP20 token) while making sure that the transaction proceeds only if both parties agree on the rules. The system also has their own BEP20 token called ChainpalsToken. The actors are incentivized to use these native tokens, which allows them to avail special discounts on fees. People are also encouraged to tell others about this protocol, for which they get bonuses in the form of NFTs and a share.

Methodology & Scope

The code came to us in the form of a zip, containing a truffle directory, the contract and the tests. Initially, we ran the contract and tested the functionality of all the functions manually. After that, we moved to Foundry to try all kinds of scenarios. After all the logical and functional testing, we moved to code optimizations and solidity design patterns to ensure consistency and readability.


Executive Summary

The analysis indicates that some of the functionalities in the contracts audited are working properly.

Our team performed a technique called “Filtered Audit”, where the contract was separately audited by two individuals. After their thorough and rigorous process of manual testing, an automated review was carried out using Surya. All the flags raised were manually reviewed and re-tested.

Our team found: 

# of issues Severity of the risk
2Critical Risk issue(s)
0High-Risk issue(s)
0Medium Risk issue(s)
2Low-Risk issue(s)
5Informatory issue(s)


1.Missing core functionalityCriticalAcknowledged
2.Misleading functionalityCriticalAcknowledged
3.Missing zero address checksLowFixed
4.Unnecessary conversionLowFixed
5.Anti-pattern checkInformatoryFixed
6.Inconsistency in error messagesInformatoryFixed
7.Spelling mistakesInformatoryFixed
8.Follow solidity design patternInformatoryFixed
9.Inconsistent code writingInformatoryFixed

Critical risk issues

1. Missing core functionality


The contract seems to have the functionality of deducting fees in BNB. The claim transaction amount function has a check that the feePaymentCurrency variable is BNB but the contract is missing the functionality of collecting fees in BNB. 

if (
       ) {
           sendBnb(feesHoldingWalletAddress, transaction.paymentAmountFees);


Write a proper code to collect fees in BNB instead of CHP when the feePaymentCurrency is set to BNB.



Developer Response:

If a user has created a transaction using two different currency platforms Fees in BNB & Transaction payment in USDT then in the smart contract there is one function name: “onChainATransactionBNB” using we are collecting platform fees(BNB) and if the user has created a transaction in the same currency for payment and platform fees(BNB) then on the time of make payment (function name: payTransactionBNB ) will collect both platform fee & payment in a single transaction.

2. Misleading functionality


The contract contains a function called transferFees() which calls the function transferFunds() to send fees to five different wallets. The transferFunds() has a hardcoded fee token address set to ChainpalsToken. Regardless of what token the user sets, the fee is always deducted in terms of the ChainpalsTokens. This is misleading because it does not function the way it is mentioned in the document.

function transferFees(Transaction memory _transaction) private {
       if (_transaction.referralAddress != msg.sender) {


Write proper implementation to go forward with the method written in the documentation, or update the documentation to go along with the existing code.



Auditor’s Response:

Since the specs document was not clear and auditors made the wrong assumptions. It is necessary for the user to hold CHP tokens in order to create/claim transactions because protocol only supports CHP tokens for transactionFees. Also it is recommended to clear/mention this spec in public doc for users. 

Low-risk issues

 3. Missing zero address checks


The constructor accepts several address parameters, none of which are being checked for zero address. There is a validateNonZeroAddress() that checks for zero addresses, which can be used here. Here are some other functions missing zero address checks:

  • createTransaction()
  • createTransactionForUnregistered()
  • addUnregisteredUserIntoTransaction()


Fixed as per BlockApex recommendation.

4. Unnecessary conversion


In the function onChainATransactionBnb(), there is a require statement which checks for (paymentAmountFees * 1 wei <= msg.value). This operation is unnecessary. It is like multiplying the entire amount with 1, which is inconsequential.

                   msg.value >=
                       ) *
                           1 wei,
                   "Invalid Amount"


Remove the unnecessary conversion.


Fixed as per BlockApex recommendation.

Informatory issues and Optimization

5. Anti-pattern check


Conventionally, the global variable is on the left-hand side of the comparison operator, with the local variable or the function parameter on the right-hand side. Most checks in the code go against this. The code is not committed to one pattern, with the variables reversed in some cases. 

           transaction.transactionDetails.buyer == msg.sender,
           "not valid buyer"
                   msg.value >=
                       ) *
                           1 wei,
                   "Invalid Amount"


Fixed as per BlockApex recommendation.

6. Inconsistency in error messages


The error messages in the require checks are inconsistent. Even for the same check, each function has a different error message. Also, the error messages should be meaningful. At the moment, some messages in the code do not tell the user what the error is supposed to mean.

           msg.sender == transaction.transactionDetails.createdBy,
           "You cannot update"


Fixed as per BlockApex recommendation.

7. Spelling mistakes


There are several cases of spelling mistakes in the code.

address public referelBonusAddress;
enum PAYMENT {
require(isTransaction(_uid) == false, "Invalid transction id");


Fixed as per BlockApex recommendation.

8. Follow a solidity design pattern


As stated in the Solidity style guide, the functions should be grouped according to their visibility and ordered:

  • constructor
  • receive function (if exists)
  • fallback function (if exists)
  • external
  • public
  • internal
  • Private


Fixed as per BlockApex recommendation.

9. Inconsistent code writing


The code has used both msg.sender and msgSender() from the Context library. It is suggested that you stick to one and use it throughout the code.

function resolveDispute(string memory _uid) external returns (bool) {
       require(isTransaction(_uid), "Invalid id");
       Transaction storage transaction = transactions[_uid];
           transaction.transactionDetails.buyer == _msgSender() ||
               owner() == _msgSender() ||
               escrowManagerAddress == _msgSender() ||
               adminAddress == _msgSender(),
           "User can not resolve the dispute."
           transaction.transactionDetails.seller == msg.sender,
           "not valid seller"


Fixed as per BlockApex recommendation.


The smart contracts provided by the client for audit purposes have been thoroughly analyzed in compliance with the global best practices till date w.r.t cybersecurity vulnerabilities and issues in smart contract code, the details of which are enclosed in this report. 

This report is not an endorsement or indictment of the project or team, and they do not in any way guarantee the security of the particular object in context. This report is not considered, and should not be interpreted as an influence, on the potential economics of the token, its sale or any other aspect of the project. 

Crypto assets/tokens are results of the emerging blockchain technology in the domain of decentralized finance and they carry with them high levels of technical risk and uncertainty. No report provides any warranty or representation to any third-Party in any respect, including regarding the bug-free nature of code, the business model or proprietors of any such business model, and the legal compliance of any such business. No third-party should rely on the reports in any way, including for the purpose of making any decisions to buy or sell any token, product, service or other asset. Specifically, for the avoidance of doubt, this report does not constitute investment advice, is not intended to be relied upon as investment advice, is not an endorsement of this project or team, and it is not a guarantee as to the absolute security of the project.

Smart contracts are deployed and executed on a blockchain. The platform, its programming language, and other software related to the smart contract can have its vulnerabilities that can lead to hacks. The scope of our review is limited to a review of the Solidity code and only the Solidity code we note as being within the scope of our review within this report. The Solidity language itself remains under development and is subject to unknown risks and flaws. The review does not extend to the compiler layer, or any other areas beyond Solidity that could present security risks.

This audit cannot be considered as a sufficient assessment regarding the utility and safety of the code, bug-free status or any other statements of the contract. While we have done our best in conducting the analysis and producing this report, it is important to note that you should not rely on this report only - we recommend proceeding with several independent audits and a public bug bounty program to ensure security of smart contracts.

More Audits

Consumer Privacy & Data Breach Part I - Is It a Global Issue?

Data breaches and consumer privacy are one of the most alarming security issues in IT space. About 45% of the world’s population uses social media which makes approximately 3.48 billion people to be interacting with any kind of social media network. These tremendous amounts of connections can lead to various kinds of vulnerabilities if the data is gone into the wrong hands creating pretty damaging consequences.

Red, Blue & Purple Team: Attacker, Defender & Facilitator

The purple team exercises allow for regular testing of controls to ensure they still function as expected. Combining red and blue functions also means that the blue team does not have to learn the red-team skills, or take the time to recreate attack behaviors themselves.

Social Engineering: Classification & Prevention

Social Engineering is an art, where an attacker manipulates people to extract confidential information. That information could be used in various ways by criminals. Individuals are targeted to install malicious software that could give cybercriminals access to their operating systems,

Euler Finance (March 14, 2023)

The Euler Finance hack had a devastating impact on the platform and its users, with approximately $197 million worth of assets stolen, including ETH, WBTC, USDC, and DAI. This placed Euler Finance at number 6 on the leaderboard of the largest DeFi hacks. The platform's total value locked (TVL) dropped from $264 million to just $10 million.

Order Matching: Achieving Seamless Trades

Decentralized exchanges (DEXs) have disrupted the cryptocurrency trading landscape by introducing trustless and transparent platforms for exchanging digital assets. A critical element of DEXs is the order matching mechanism, which enables the execution of trades. This blog post delves into the intricacies of order-matching mechanisms, highlighting the advancements that have enhanced user efficiency, liquidity, and overall trading experience.

Lightlink Bridge - Audit Report

BlockApex (Auditor) was contracted by LightLink (Client) for the purpose of conducting a Smart Contract Audit/ Code Review. This document presents the findings of our analysis, which started on 12th June ‘2023.

Unipilot Farming V2 Audit Report

BlockApex (Auditor) was contracted by  VoirStudio  (Client) for the purpose of conducting a Smart Contract Audit/ Code Review of Unipilot Farming V2. This document presents the findings of our analysis which started from  25th Feb 2022.

Chainpals Presale Audit Report

The presale is supposed to go forward in three stages, each with fixed purchasable amounts and at a fixed cost. The cost starts off at 0.25 USD in the first phase, moves to 0.35 USD in the second phase and then to 0.45 in the last phase.

HUNDRED FINANCE - April 15, 2023

On April 15th, 2023, Hundred Finance was hacked, resulting in a loss of approximately $7.4 million USD in various cryptocurrencies. The attacker exploited an integer rounding vulnerability in the platform's contract logic when a market was empty.

1 2 3 11
Designed & Developed by: 
All rights reserved. Copyright 2023