JamAI

CertiKRepository at commit 4b7e9a8

CertiK reviewed JAM (JamAI) on 10 Jan 2025: 13 findings, 0 critical; 6 marked fixed, 7 acknowledged.

No open critical findings
Open the reportOpen JAM’s security record

Report hosted on skynet.certik.com.

Trustblock does not review code.

Findings13

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

SeverityOpenAcknowledgedFixed
Critical000
High020
Medium001
Low055
HighCentralization Related RisksAcknowledged

In the contract `JamAI`, the role `_owner` has authority over the functions shown in the diagram below. Any compromise to the `_owner` account may allow the hacker to take advantage of this authority and set the threshold, set the jammer address, set the buy fee rate, update token information, set the sell fee rate, enable or disable selling, set the fee recipient address, and set the trade approver address. ![](https://accelerator-tasks-prod.acc.corp.certik.com/11ef-c876-c44e0bc0-807d-2790b1b8c5df/diagrams/centralization_JamAI-JamAI-_owner.svg) --- In the contract `Jammer`, the role `_owner` has authority over the functions shown in the diagram below. Any compromise to the `_owner` account may allow the hacker to take advantage of this authority and set the LP treasury address, set the default locking period, set the fee recipient address, and set the JamAI address. ![](https://accelerator-tasks-prod.acc.corp.certik.com/11ef-c876-c44e0bc0-807d-2790b1b8c5df/diagrams/centralization_Jammer-Jammer-_owner.svg) --- In the contract `LPTreasury`, the role `_owner` has authority over the functions shown in the diagram below. Any compromise to the `_owner` account may allow the hacker to take advantage of this authority and rescue a specified ERC721 token for a given receiver, set the token recipient address, set the fee recipient address, and release the token to the recipient after a time check. It should be noted that the recipient can remove liquidity from the pool at any time, which could even lead to the depletion of liquidity in the pool. ![](https://accelerator-tasks-prod.acc.corp.certik.com/11ef-c876-c44e0bc0-807d-2790b1b8c5df/diagrams/centralization_LPTreasury-LPTreasury-_owner.svg) --- The owners of `JamAI`/`Jammer`/`LPTreasury` also have authority over the functions shown below. Any compromise to the owners' account may allow the hacker to take advantage of this authority and transfer ownership to any account or renounce ownership maliciously. - transferOwnership() - renounceOwnership() Additionally, the LP of the activated pools will also be locked in the `LPTreasury` contract and can be transferred to a `tokenRecipient` account. If this account is compromised, a hacker could exploit this authority to remove the LP, potentially disrupting the token market.

HighInitial Token DistributionAcknowledged

All of the tokens are sent to the contract deployer or one or several externally-owned account (EOA) addresses. This is a centralization risk because the deployer or the owner(s) of the EOAs can distribute tokens without obtaining the consensus of the community. Any compromise to these addresses may allow a hacker to steal and sell tokens on the market, resulting in severe damage to the project.

LowConcerns on The Creator of TicketAcknowledged

In the `startTrading()` function, a ticket is generated for the creator when trading begins. According to the `sellTickets()` function, the last remaining ticket cannot be sold. If the creator sells their ticket before all the buyers have done so, the final ticket held by a buyer cannot be sold, potentially resulting in a loss.

LowExcess Tokens Paid Will Not Be RefundedAcknowledged

In the `_buyTickets()` function, the function requires users to pay an amount of native tokens no less than the ticket price plus the protocol fee. ```solidity function _buyTickets(address buyer, uint256 aiAgentId, uint256 amount) internal { if (!tradeEnabled[aiAgentId]) revert TradeNotEnabled(); if (pools[aiAgentId] != address(0)) revert PoolLaunched(); uint256 supply = ticketsSupply[aiAgentId]; uint256 price = getPrice(supply, amount); uint256 protocolFee = price * buyFeeRate / 1000; if (msg.value < price + protocolFee) revert InsufficientPayment(); ticketsBalance[aiAgentId][buyer] = ticketsBalance[aiAgentId][buyer] + amount; ticketsSupply[aiAgentId] = supply + amount; emit Trade(buyer, aiAgentId, true, amount, price, protocolFee, supply + amount); if (price > 0) { (bool success, ) = feeTo.call{value: msg.value - price}(""); if(!success) revert TransferFailed(); } } ``` However, any excess amount is treated as a protocol fee and sent entirely to `feeTo`, which may result in a loss for the user.

LowLack of Buyer Account In the Verified MessageAcknowledged

The `startTrading()` function allows users with a valid signature to purchase tickets using `ETH`. However, the verified message does not include the buyer's address. Consequently, other accounts are able to front-run the buyer's transaction and purchase the tickets themselves.

LowPotential Exploit By Buying And Selling TicketsAcknowledged

In the design of the `JamAI` contract, users are allowed to buy and sell tickets before the associated Uniswap v3 pool is activated. When purchasing tickets, the payment amount is calculated using the `getPrice()` function, which takes `ticketsSupply[aiAgentId]` and `amount` as input parameters. When selling tickets, users can receive their investment back, minus a fee. The value of the investment is also determined by the `getPrice()` function, which takes `ticketsSupply[aiAgentId]-amount` and `amount` as input parameters. This function employs a sum of squares formula to compute the amount to be paid or refunded. The formula creates an opportunity for exploitation, as users can potentially gain by executing buy and sell transactions due to variations in the sum of squares during these operations.

LowThird-Party Dependency UsageAcknowledged

The contract is serving as the underlying entity to interact with one or more third party protocols. The scope of the audit treats third party entities as black boxes and assumes their functional correctness. However, in the real world, third parties can be compromised and this may lead to lost or stolen assets. In addition, upgrades of third parties can possibly create severe impacts, such as increasing fees of third parties, migrating to new LP pools, etc. ```solidity=27 address public immutable WETH; ``` - The contract `Jammer` interacts with third party contract with `WETH`. ```solidity=28 IPancakeV3Factory public immutable pancakeV3Factory; ``` - The contract `Jammer` interacts with third party contract with `IPancakeV3Factory` interface via `pancakeV3Factory`. ```solidity=29 INonfungiblePositionManager public immutable positionManager; ``` - The contract `Jammer` interacts with third party contract with `INonfungiblePositionManager` interface via `positionManager`. ```solidity=30 IPancakeV3SwapRouter public immutable swapRouter; ``` - The contract `Jammer` interacts with third party contract with `IPancakeV3SwapRouter` interface via `swapRouter`. ```solidity=19 INonfungiblePositionManager public immutable positionManager; ``` - The contract `LPTreasury` interacts with third party contract with `INonfungiblePositionManager` interface via `positionManager`.

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 (4)

  • https://github.com/jam-so/jam-ai-contracts/contracts/JamAI.sol at commit 4b7e9a8ef0fdbc7bf6b25aa41521535b2d1b4704
  • https://github.com/jam-so/jam-ai-contracts/contracts/LPTreasury.sol at commit 4b7e9a8ef0fdbc7bf6b25aa41521535b2d1b4704
  • https://github.com/jam-so/jam-ai-contracts/contracts/AIAgentToken.sol at commit 4b7e9a8ef0fdbc7bf6b25aa41521535b2d1b4704
  • https://github.com/jam-so/jam-ai-contracts/contracts/Jammer.sol at commit 4b7e9a8ef0fdbc7bf6b25aa41521535b2d1b4704

Part of JAM’s security record

JAM
Audits1 audit by 1 firmLast audit Jan 2025, by CertiK.
Critical findingsNo open critical findingsIn 1 report.
Open JAM’s security record

Security firm

CertiK

1,044 projects reviewed · 1,375 reports · latest May 2025

See CertiK’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