As of 3 Nov 2026, ChainPort Cross-Chain Bridge has 5 audit reports by 2 security firms on Trustblock; the latest is by Zokyo, dated 3 Jan 2024. Those reports list no open critical findings.
Record last updated . It holds audits, findings and contracts up to Nov 2026, and incidents up to Oct 2026. Trustblock does not review code.
Newest first
| Audit | Security firm | Date | Scope | Critical findings | Report |
|---|---|---|---|---|---|
| Chainport | Security firm: Zokyo | Date: | Scope: Not recorded (see the report) | No open critical findings | Open · IPFS |
| Chainport2023 | Security firm: CertiK | Date: | Scope: Not recorded (see the report) | No open critical findings | Open · skynet.certik.com |
| Chainport (PORT) | Security firm: CertiK | Date: | Scope: Not recorded (see the report) | No open critical findings | Open · skynet.certik.com |
| Chainport (Sol part) | Security firm: CertiK | Date: | Scope: Files named in the report | No open critical findings | Open · skynet.certik.com |
| ChainPort-Cardano Bridge | Security firm: CertiK | Date: | Scope: Not recorded (see the report) | 1 critical finding, fixed | Open · skynet.certik.com |
Statuses are the security firm’s own, from each report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 0 |
| High | 0 | 6 | 1 |
| Medium | 8 | 0 | 4 |
| Low | 20 | 0 | 24 |
Code at the pointed lines searches on the persistent storage for transaction with the given `data_passed` on the provided `network_id`. Then, if such transaction is found the `mint_bridge_tokens` returns with no-operations. The data passed in the `data_passed` parameter includes the transaction signature computed in line 94. The signature algorithm of Ethereum accounts is ECDSA which is based on random one-time-use numbers for signature generation. This means that distinct signatures of the same data by the same account are different. So, querying a transaction by including the signature as a parameter is always going to fail since each transaction, even if containing the same data, will produce different signatures. As a result, the logic to exit the `mint_bridge_tokens` function if `prev_tx_obj` is found is not able to detect already created transactions.
Open the reportThe `cardano_one_time_minter` function mints Cardano tokens and tracks them by saving the new token information on the database. However, no data about the on-chain transaction that caused such mint is contextually stored with the minting operation. As a result, if the `cardano_one_time_minter` handler is called twice (e.g. because of bugs in the calling logic, misconfiguration of cloud resources, ...) in reference to the same on-chain event, then two distinct mint actions are executed, and proportion between locked tokens and minted ones is altered.
Open the reportVariable with string (`asset_name`) and (`token_name`) is salted with postfix and truncated to first 32 bytes without checking it's length. This may result in collision attack or bugs of wrong parameters in the case of 0 length strings or names which differ only for characters after the 31st.
Open the reportThe function `cardano_one_time_minter()` calls the function `mint_one_time_token()` on the Cardano object in order to mint a new token. Subsequently, code at the pointed locations, updates the off-chain persistent storage. However, such storage updates may fail (e.g. for a database connection issue), trigger an Exception and leave the off-chain logic in an outdated state in respect to what happened on-chain. Considering the the off-chain logic drives the bridge business logic, this condition must be avoided.
Open the reportThe function `burn_utxo()` from `cardano.py` performs three operations on a `try` statement. If any of those operations fail to throw an error, the `except` block will execute. Two of those operations are network related and are prone to fail due to connection errors. But, an issue might arise if one operation was performed successfully and the other one is not (for example, if the slack bot is down). The transaction submission was successful but the slack message threw an exception, the function will return `None` as the transaction hash, losing the correct hash that corresponds to the transaction. A similar issue occurs on the functions `release_tokens()`, `mint_one_time_token()` and `mint_token()` from the same file.
Open the reportThe code at the pointed lines submits a transaction to the network and saves such information on the persistent storage. However, if the transaction submission fails for any reason, there is no error handling to either recover from the failure or investigate the reason of the failure. Moreover, if the error on the transaction submission happens while decoding the answer from the service through which the transaction was submitted, the system could be exposed to a replay of the minting transaction in reference to the same deposit. In fact, if the transaction gets included in the chain but the code fails before saving such information, then the system is in the state in which a new minting operation is issued, which causes a loss of funds.
Open the reportThe function `initialize()` is `public` and can be called by anyone as long as the contract is deployed.
Open the reportCross-chain token transfer depends on the third-party cross-chain protocol. If the cross-chain protocol is hacked, the `Chainprot` protocol in the side chain cannot confirm the transaction status correctly. As a result, the user burns tokens in the side chain but cannot receive them in the target chain.
Open the reportThe functions `session_get_pending_cardano_burn_transactions()`, `session_get_pending_cardano_deposit_transactions()` and `session_get_pending_cardano_mint_transactions()` from `cardano_transaction.py` are almost identical. The shared functionality could be extracted into a separate function from which the linked functions could use with their needed `transaction_type`.
Open the reportThe linked statements are meant to configure the environment on which the script will run. On the platform chosen by the client to deploy the scripts (AWS), the configuration is done outside the code, either via the console or via another script (like terraform). Moreover, lambdas should get their environment variables and context from the `context` parameter. Additionally, the linked whitelists could be defined externally. The reason is that if a change needs to be made into one, there is no need to redeploy the lambdas.
Open the reportIn the function `session_get_latest_cardano_event_counter_by_name` the function returns `1` if a `CardanoBridgeEvent` is not matching with any `name` and `res.counter + 1` if the `name` matches an existing `CardanoBrdigeEvent`. Starting the counter from `0` can avoid the necessity of adding `1` to `res.counter` when the condition is met.
Open the reportIn the function `get_or_create_cardano_deposit_transaction_and_bridge_event` the `deposit_transaction_obj.id` is assigned to two different variables, respectively `bridge_event_obj.deposit_tx` and `bridge_event_obj.burn_tx`, that are stored in DB resulting in a duplicated field.
Open the reportMost functions in the codebase are missing types and input values sanitation. Since parameter types in python are suggestions not enforced, it can lead to processing other types as inputs that were anticipated. Additionally, the above functions should document ranges of expected inputs and proper sanitation of input parameters ensured.
Open the reportThe name `burn` of the address used for recording and monitoring deposits on the Cardano blockchain is misleading. In web3 world, a burn address is a digital wallet that can't be accessed because it doesn't have a private key attached to it, however, as shown in the commented out of code function `move_utxos_from_burn_address` seems the team has a different idea behind the `burn` address. Indeed the burn address is used in the codebase as a `deposit` address. Misleading naming may lead users to use system in a way they did not intent do - e.g. they may expect certain guarantees from `burn` address, and otherwise they may have decided on different strategy of moving their funds.
Open the reportThe linked function has almost 300 Lines of Code. This amount reduces the code's readability and maintainability.
Open the reportThe linked statements contain typos: - "addess" should be "address" - "maintaner_addresss" should be "maintainer_address" - "benficiary" should be "beneficiary" - "carando" should be "cardano" - "cardaon" should be "cardano" - "policys" should be "policies" - "recieved_sum" should be "received_sum" - "reciever_address" should be "receiver_address" - "fee_reciever_web3_identity_id" should be "fee_receiver_web3_identity_id" - "cardano_reciever_web3_identity_obj" should be "cardano_receiver_web3_identity_obj" - "returuns" should be "returns" - "submiting" should be "submitting" - "transaciton" should be "transaction" - "useable" should be "usable" - "verifcation_key" should be "verification_key" - "verificaiton" should be "verification" - "issuer_web3_addess" should be "issuer_web3_address"
Open the reportThe function `is_multi_asset_utxco_useable()` defines the parameter `asset_value` as a string. Then, when using the variable, it is cast into an integer. Moreover, the function's caller casts the `asset_value` parameter into a string. These casts are redundant because the parameter could be used directly on its `int` representation. If it was intended to take `asset_value` as string, then should be considered logic that handles if provided data does not adhere expected format , leading to incorrect conversion to integer. Otherwise, ensure proper integer was provided as input.
Open the reportThe linked local variables are not necessary and their value can be used directly. This would improve the code's readability.
Open the reportThe pointed variables are declared but never used in the codebase. E.g. in function `is_valid_deposit_utxo` the variable `_` is filled with the `target_network_id` taken from `transaction_metadata`, however, it is never used inside the function.
Open the reportDifferent magic numbers are used as-is in code.
Open the report`public` functions that are never called by the contract could be declared as `external`. `external` functions are more efficient than `public` functions.
Open the reportWhen transferring standard ERC20 deflationary tokens, the input amount may not be equal to the received amount due to the charged transaction fee.
Open the reportThere should always be events emitted in the sensitive functions that are controlled by centralization roles.
Open the reportThe **require** can be used to check for conditions and throw an exception if the condition is not met. It is better to provide a string message containing details about the error that will be passed back to the caller.
Open the reportThe given input is missing the check for the non-zero address.
Open the reportThe `token` address is alway the address of `_chainportToken`, so the variable is redundant.
Open the reportThe contract is serving as the underlying entity to interact with third-party `ChainportMiddlewareV2`, `ChainportMiddleware`, `IBridgeMintableTokenV2`, `IValidator` protocols. The scope of the audit treats 3rd party entities as black boxes and assume their functional correctness. However, in the real world, 3rd parties can be compromised and this may lead to lost or stolen assets. In addition, upgrades of 3rd parties can possibly create severe impacts, such as increasing fees of 3rd parties, migrating to new LP pools, etc.
Open the reportThe linked lines can be replaced with the modifier `onlyIfCreatedByTheBridge`.
Open the reportThe reports name a repository or files. Open a report to see its scope.
Is this your project? Show this record on your own website. The label states what the record holds, links to this page and updates by itself. It is free and needs no sign-in.
Automatic: the three strongest facts of this project’s own record (its last audit and two more), highlighted. They update with the record. Picking a fact turns Automatic off.
<head><script src="https://widget.trustblock.run/project-widget.min.js" defer></script></head><body><divdata-tb-project-widgetdata-tb-project-slug="chainport-cross"></div></body>
Paste the code where the label should appear. It uses no API credit and updates by itself.
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