Cover Image for How to Audit Blockchain Wallets : A Step-by-step Guide​

How to Audit Blockchain Wallets : A Step-by-step Guide​

Analysis
Reconciliation

While the concept, purpose, and aim are the same, financial auditing for blockchain wallets is different from the conventional auditing process.

Traditional financial audits involve the review of a company’s financial statement to check for discrepancies and correlations. The auditor verifies the records and statements of a company to see if they are accurate and in fair representation of the firm’s financial situation and transactions. You also check if there are misstatements or malpractices in the calculation and generation of financial statements.

On the other hand, blockchain wallet/account auditing is also related to the traditional financial audit processes. The only difference is that blockchain wallet auditing uniquely focuses on transactions recorded on the blockchain, utilizing the immutable and transparent nature of the blockchain ledger. This process employs cryptographic proofs and specialized tools to ensure the integrity and validity of transactions.

What’s the Main Purpose of Auditing a Blockchain Wallet?

The primary purpose of a blockchain wallet audit is to ensure the accuracy, integrity, and security of transactions recorded on the blockchain, verifying that the financial records are free from any material misstatements due to errors or fraud.

This process involves not only checking for financial discrepancies but also ensuring compliance with regulatory requirements, ensuring compliance with regulatory requirements, verifying the proper execution of smart contracts, and accessing the overall security and performance of the wallet and associated system.

For example, in this judgment text from the High Court of the Republic of Singapore, where an employee, Ho Kai Xin, makes eight anomalous transactions to four crypto addresses. Through crypto reconciliation and blockchain wallet auditing, Bybit was able to discover discrepancies, which led to the prosecution of the said employee.

With auditing and reconciliation processes, auditors can identify inconsistencies and discrepancies in finances. While the above auditing and reconciliatory work as mentioned in the litigation was done using a Microsoft Excel sheet, blockchain analytical tools like Bitquery can be reliably used because of their transparency, immutability, and security.

In this article, we’ll discuss how to conduct financial audits and reconciliation processes for digital assets to gain insights and detect anomalies using Bitquery APIs and Explorers. Without ado, let’s get to it!

How to Conduct Proper Blockchain Wallet Audits and Reconciliatory Works Using Bitquery APIs and Explorer?

Bitquery is a blockchain analytical company that indexes, parses, stores, and analyzes blockchain data. This data tool offers access to over 40 blockchains and 100 DEX protocols. With this extensive data tool, we can audit and reconcile blockchain wallets with ease.

Without much ado, here is a simple tutorial on how to use Bitquery APIs and explorers to audit on-chain information against a company's transaction records.

  1. Transaction Data Collection and Verification

Blockchain wallet auditing requires planning. This section is where you identify the wallet(s) you’re required to audit as an external auditor. Here is where you’re given access to the information you need.

Below is a wallet we’ll be working with through this tutorial article:

0x7BFEe91193d9Df2Ac0bFe90191D40F23c773C060

Let’s assume that’s a company blockchain wallet and you’re required to perform auditing and reconciliatory work on the wallet between the first of March to the 30th of May 2024. You’ve also been given access to the company’s on-chain transaction record.

  1. Accessing Blockchain Explorer and Checking Wallet Address

Here is where you conduct the systematic collection of data and records from the blockchain network to support the audit process. Using the Bitquery Transfers API, you can retrieve information like transaction history, wallet balance as at the start of the audit process, and other useful and relevant information shared on the blockchain.

With this total deposit query, we retrieve the necessary information about the total deposit within the specified period, i.e., April 30 to May 30 2024.

{
  ethereum(network: ethereum) {
    transfers(
      date: {since: "2024-03-01", till: "2024-05-30"}
      amount: {gt: 0}
      receiver: {is: "0x7BFEe91193d9Df2Ac0bFe90191D40F23c773C060"}
    ) {
     Deposits:  count(success: true)
    }
  }
}

While this query helps us retrieve the total count of transfers from the wallet to other wallets

{
  ethereum(network: ethereum) {
    transfers(
      date: {since: "2024-03-01", till: "2024-05-30"}
      amount: {gt: 0}
      sender: {is: "0x7BFEe91193d9Df2Ac0bFe90191D40F23c773C060"}
    ) {
     Withdrawal:  count(success: true)
    }
  }
}

With the above queries, we discovered that the total deposit count (transaction received) for this wallet over the three month period is 1403. While the total withdrawal count (transaction sent out from the wallet holder) was 571 transactions.

While this information gives you a broad overview of the data you will be working with, you still don’t have access to the detailed information (block information, transaction information, sender and receiver address, amount, currency, and so on) concerning the transactions.

And so, with this received transaction query, you can pull all the necessary information (block information, sender address, token information) you need for the auditing and reconciliation work.

{
  ethereum(network: ethereum) {
    transfers(
      date: {since: "2024-03-01", till: "2024-05-30"}
      amount: {gt: 0}
      receiver: {is: "0x7BFEe91193d9Df2Ac0bFe90191D40F23c773C060"}
      options: {asc: "block.timestamp.time", limit: 20}
    ) {
      block {
        height
        timestamp {
          time
        }
      }
      sender {
        address
      }
      currency {
        name
        symbol
        tokenType
      }
      amount
      amountInUSD: amount (in:USD)
      transaction {
        hash
      }
    }
  }
}


Alternatively, to retrieve the necessary information about the transaction sent out by this wallet address owner, you can do so with this sent transaction query below:

{
  ethereum(network: ethereum) {
    transfers(
      date: {since: "2024-03-01", till: "2024-05-30"}
      amount: {gt: 0}
      sender: {is: "0x7BFEe91193d9Df2Ac0bFe90191D40F23c773C060"}
      options: {asc: "block.timestamp.time", limit: 20}
    ) {
      block {
        height
        timestamp {
          time
        }
      }
      receiver {
        address
      }
      currency {
        name
        symbol
        tokenType
      }
      amount
      amountInUSD: amount (in:USD)
      transaction {
        hash
      }
    }
  }
}


With the appropriate tools like the Bitquery APIs, you can retrieve all transaction information recorded on the blockchain and reconcile them against the company’s transaction record.

However, if you’re not the technical type, you can access the necessary information about the wallet without writing any query. All you have to do is visit Bitquery Explorer and insert the wallet address and filter by the date range.

  1. Calculating Balances and Comparing With Recorded Balance

Once you’ve retrieved the transaction history (both the incoming and outgoing transactions linked to the wallet address) as we’ve done in the previous step, you can now calculate the wallet’s balance.

With the total transfer over the time period query, you’d get the total balance of each token in the wallet as at May 30,2024. Moreover, you also know the total number of times a particular token is deposited and withdrawn from the wallet. Here is the example query below:

query ($network: EthereumNetwork!, $address: String!, $from: ISO8601DateTime, $till: ISO8601DateTime, $limit: Int!, $offset: Int!) {
  ethereum(network: $network) {
    transfers(
      date: {since: $from, till: $till}
      amount: {gt: 0}
      any: [{receiver: {is: $address}}, {sender: {is: $address}}]
      options: {limit: $limit, offset: $offset, desc: ["count_in", "count_out"], asc: "currency.symbol"}
    ) {
      sum_in: amount(calculate: sum, receiver: {is: $address})
      sum_in_usd: amount(in: USD, calculate: sum, receiver: {is: $address})
      sum_out: amount(calculate: sum, sender: {is: $address})
      sum_out_usd: amount(in: USD, calculate: sum, sender: {is: $address})
      count_in: count(receiver: {is: $address})
      count_out: count(sender: {is: $address})
      currency {
        address
        symbol
        tokenType
      }
    }
  }
}

The query above retrieves the Ethereum token transfer data for a specified address, within a given date range, on a specified Ethereum network. It filters transfers where the address is either the sender or receiver and includes only transfers with a positive amount.

The query also limits the number of records returned, supports pagination, and sorts results by the number of transfer and token symbols. It calculates the total amount received and sent in both the native token and USD), and also counts the number of incoming and outgoing transfers.

Additionally, it provides details about the token involved including, their contract address, symbol, and type.

Finally, once you’ve gotten the net balance of the tokens in the wallet over the specified period, you can now compare the retrieved data with the recorded balances from the on-chain explorer and ensure there are no discrepancies between the calculated balances and the recorded balances.

Using the query above, below is Ethereum token balance information we got:

"sum_in": 420070.7241165968,
 "sum_in_usd": 413614.71519630746,
"sum_out": 420009.9315213211,
"sum_out_usd": 413604.35966727405,
"count_in": 49,
"count_out": 10,
"currency": 
"address": "0x15f74458ae0bfdaa1a96ca1aa779d715cc1eefe4",
          "symbol": "GRAI",
          "tokenType": "ERC20"

Summary of the Information

  • The wallet has an ERC20 token named GRAI with a smart contract address: 0x15f74458ae0bfdaa1a96ca1aa779d715cc1eefe4.

  • Over the course of three months (between march and may), the wallet received a total of 420,070 GRAI, which is worth $413,614.72.

  • On the other hand, a total of 420009 GRAI, which is worth $413,604.35 was sent out by the wallet owner in the same period. All things being equal, this means that the wallet should be holding around 61GRAI.

  • Finally, the total transaction count is 59 with 49 out of the 59 total transactions sent from an external wallet while the remaining 10 transfer count was from the wallet to external wallets.

Check through the data using the above information while comparing with the recorded transaction details from the company. With this information, you should be able to discover discrepancies and anomalies if there are any. If there are any anomalies, the next step below will be on how to investigate the error or fraud and find the most suitable solution to it.

  1. Investigating Discrepancies

By conducting a thorough investigation of discrepancies, auditors can ensure the integrity and accuracy of financial information, which will enhance trust and reliability.

If there seem to be discrepancies between the recorded and the calculated balance, you should dig deep into the transaction information to identify any anomalies or irregularities.

This can be done by systematically analyzing transactional data (like the amount, timestamp, transaction fees, wallet addresses, and transaction pattern) to identify and resolve the inconsistency.

For example, let’s say that the GRAI token information we pulled above using the Bitquery API doesn’t correlate with the data received on the company transaction record.

What should you do?

The first thing to do at this stage is to zoom in on the information available. And that means pulling the transaction information of the token over the three month period. This can be done using the token transfer details query for details about the incoming transaction or the token transfer details (outgoing) query for the outgoing transactions.

Here is the query for retrieving the necessary details about token transfer information for the incoming transactions:

query ($network: EthereumNetwork!, $address: String!, $limit: Int!, $offset: Int!, $currency: String!, $from: ISO8601DateTime, $till: ISO8601DateTime) {
  ethereum(network: $network) {
    transfers(
      options: {desc: "block.timestamp.time", limit: $limit, offset: $offset}
      date: {since: $from, till: $till}
      amount: {gt: 0}
      currency: {is: $currency}
      sender: {is: $address}
    ) {
      block {
        timestamp {
          time(format: "%Y-%m-%d %H:%M:%S")
        }
        height
      }
      address: receiver {
        address
        annotation
      }
      currency {
        address
        symbol
      }
      amount
      transaction {
        hash
      }
      external
    }
  }
}

With the data retrieved, you can look through the transaction history gathered from the blockchain ledger with the recorded transaction data provided by explorers or wallet providers, ensuring that the details were accounted for and accurately reflected in both sets of data.

If you discovered that there are some errors or elements of fraud in what you see, here are ways to dig deep and investigate these discrepancies further:

  1. Trace the flow of funds through blockchain networks to verify the legitimacy of transactions and confirm their impact on the wallet’s balance. You can trace the origin and destination of funds as well as any intermediate transactions using the Coinpath API or request an investigation by Bitquery’s service.
  1. Validate cryptographic signatures, and verify transaction confirmations on the blockchain network. And ensure transactions were not fraudulent or manipulated. You can also use the transaction hash obtained from the transaction detail information to trace and verify transactions on the blockchain.
  1. Check and identify any patterns or trends in the transaction data that could explain discrepancies in the balances. Like recurring transactions, large withdrawals and deposits, and unusual activity that deviates from typical usage data.
  1. Once you identify the issues, you take corrective actions to reconcile the balance and ensure accuracy. Corrective actions like updating transaction records, correcting data errors, and adjusting balance calculations accordingly.

5. Documenting Reconciliation Processes and Reporting

This process involves recording the steps taken to compare and resolve discrepancies between two sets of records or accounts. Here are the processes you should take for reporting your audit work.

  1. Provide an Overview of the Process

You should provide a detailed note about the records being reconciled and accounts audited and specify the period or transactions covered by the reconciliation.

  1. Data sources, steps taken, and the reconciliation methodology

What’s your source of data? blockchain explorer, ledger, wallet accounts? Is your process/methodology manual, automated, or both? What steps were taken to identify discrepancies and compare the data? What is the detail of the adjustments, corrections, or reclassifications made during the process?

  1. How were the discrepancies discovered, investigated, and resolved

What corrective actions were taken to address, and identify errors and discrepancies like adjustments to transaction records and account balance?

  1. Documentation of findings and reporting

Record the result of the reconciliation process like the final reconciled balance, or adjustments, made to account for discrepancies. And you should also explain unresolved differences and document outstanding issues. And finally, prepare a report to summarize the findings and conclude the reconciliation process.

In conclusion, as blockchain technology continues to evolve, so too must our understanding of its intricacies and potential vulnerabilities. This article has shed light on the complexities involved in auditing blockchain wallets, from planning the process to gathering transaction data, navigating the challenges, and uncovering discrepancies due to error or fraud.

Ultimately, the findings and insights gleaned from this article will not only enhance the security and integrity of the audited wallet but also contribute to broader discussions on best practices for blockchain security and regulatory compliance. By applying the lessons learned from this article, stakeholders can better safeguard their assets, mitigate risks, and prevent any form of material misstatement due to fraud or mistakes.

--

Written by Emmanuel Ajala

Subscribe to our newsletter

Subscribe and never miss any updates related to our APIs, new developments & latest news etc. Our newsletter is sent once a week on Monday.