Judging

GTE Spot CLOB and Router

GTE is the world's fastest decentralized exchange. We’ve vertically integrated every aspect of trading - from token creation, to spot and perpetuals - to give you the best on-chain experience possible.

  • Start date23 Jul 2025
  • End date6 Aug 2025
  • Total awards$63,250 in USDC
  • Duration14 days

GTE Spot CLOB and Router audit details

  • Total Prize Pool: $63,250 in USDC
    • HM awards: up to $57,600 in USDC
      • If no valid Highs or Mediums are found, the HM pool is $0
    • QA awards: $2,400 in USDC
    • Judge awards: $3,000 in USDC
    • Scout awards: $250 in USDC
  • Read our guidelines for more details
  • Starts July 23, 2025 20:00 UTC
  • Ends August 6, 2025 20:00 UTC

❗ Important notes for wardens

  1. A coded, runnable PoC is required for all High/Medium submissions to this audit.
  • This repo includes a basic template to run the test suite under the test/c4-poc folder.
  • PoCs must use the test suite provided in this repo. For more information, consult the Creating a PoC chapter of this document.
  • Your submission will be marked as Insufficient if the POC is not runnable and working with the provided test suite.
  • Exception: PoC is optional (though recommended) for wardens with signal ≥ 0.68.
  1. Judging phase risk adjustments (upgrades/downgrades):
  • High- or Medium-risk submissions downgraded by the judge to Low-risk (QA) will be ineligible for awards.
  • Upgrading a Low-risk finding from a QA report to a Medium- or High-risk finding is not supported.
  • As such, wardens are encouraged to select the appropriate risk level carefully during the submission phase.

Automated Findings / Publicly Known Issues

The 4naly3er report can be found here.

Note for C4 wardens: Anything included in this Automated Findings / Publicly Known Issues section is considered a publicly known issue and is ineligible for awards.

CLOB Fill Rounding

On CLOB fill, filled amounts are rounded down to the nearest lot. FOK fill orders should not revert if only the amount rounded off is left unfilled, and the user is not charged for the dust. How we state we handle it may have valid issues to target in case any severe loss or otherwise unintended consequence can be demonstrated.

Transient Transaction Limit Error in Amendments

A finding was erroneously disclosed during the code walkthrough that was provided while the contest was ongoing. This finding relates to how the transient limit "maximum limit orders placed per transaction" is not properly incremented during amend() invocations.

As this vulnerability was publicly disclosed, it should be considered out-of-scope. Any submissions that were created prior to the dissemination of the code walkthrough will be considered in-scope.

Overview

GTE onchain Central-Limit Order Book

The order book is an exchange design that resembles traditional finance. For any given asset pair, an order book maintains a bid and ask side – each one being a list of buy and sell orders, respectively.

Each order is placed at a different price level, called a limit, and has an order size, which represents the amount of the trade asset that the order wants to buy or sell. Order books use an algorithmic matching engine to match up buy and sell orders, settling the funds of orders that fulfill each other.

Most order books use “price-time priority” for their matching engines, meaning that the highest buy offers and lowest sell offers are settled first, followed by the chronological sequence of orders placed at that limit price.

GTE leverages its high-performance infrastructure to offer Spot Central Limit Order Books for direct trading of assets with immediate settlement.


Scope

Files in scope

ContractSLOCLibraries used
contracts/account-manager/AccountManager.sol211N/A
contracts/clob/CLOB.sol549contracts/utils/interfaces/IOperator.sol
contracts/utils/Operator.sol
contracts/utils/types/OperatorHelperLib.sol
contracts/utils/types/EventNonce.sol
@solady/utils/SafeCastLib.sol
@solady/utils/FixedPointMathLib.sol
@openzeppelin-contracts-upgradeable/access/Ownable2StepUpgradeable.sol
contracts/clob/CLOBManager.sol179contracts/utils/types/EventNonce.sol
@solady/utils/Initializable.sol
@solady/utils/SafeTransferLib.sol
@solady/utils/FixedPointMathLib.sol
@solady/auth/OwnableRoles.sol
@openzeppelin/token/ERC20/extensions/IERC20Metadata.sol
@openzeppelin/proxy/beacon/BeaconProxy.sol
contracts/clob/ICLOB.sol70
contracts/clob/ICLOBManager.sol21
contracts/clob/ILimitLens.sol6
contracts/clob/types/Book.sol323contracts/utils/types/EventNonce.sol
contracts/clob/types/FeeData.sol81contracts/utils/types/EventNonce.sol
@solady/utils/SafeTransferLib.sol
@solady/utils/FixedPointMathLib.sol
contracts/clob/types/Order.sol66
contracts/clob/types/RedBlackTree.sol45@solady/utils/RedBlackTreeLib.sol
contracts/clob/types/Roles.sol11
contracts/clob/types/TransientMakerData.sol102
contracts/router/GTERouter.sol202contracts/clob/types/Order.sol
contracts/clob/ICLOBManager.sol
contracts/launchpad/interfaces/ILaunchpad.sol
contracts/clob/ICLOB.sol
@permit2/interfaces/IAllowanceTransfer.sol
@solady/tokens/WETH.sol
@solady/utils/SafeTransferLib.sol
@solady/utils/FixedPointMathLib.sol
@solady/utils/ReentrancyGuardTransient.sol
contracts/utils/Operator.sol51
contracts/utils/types/EventNonce.sol22
contracts/utils/types/OperatorHelperLib.sol24
Totals1963

For a machine-readable version, see scope.txt

Files out of scope

For a machine-readable version, see out_of_scope.txt

Additional context

Areas of concern (where to focus for bugs)

Rounding / Overflows

Any form of rounding / overflow with regards to order filling / order amendment that can result in someone erroneously receiving more tokens than they deserve is unacceptable. Neither party in a trade, taker nor maker, should end up with more tokens than either had available to match.

Denial-of-Service Attacks

The main type of DOS we are worried about is Order Flooding. Order Flooding is when someone crowds either the top, or a distant price in the book with many orders that would take many transactions to clear, thus slowing down everyone's ability to price the book equally to the broader market. We currently implement a minOrderSize and maxLimitsPlacedPerTx to combat this, but we do not have admin cancel.

We are mulling the idea of allowing admin cancels so long as the orders being cancelled are under a certain % of the spot oi, or far enough away from top of book, but its not in scope to discuss the viability of this.

We want to make sure that our intended goal of 1) not letting non-whitelisted callers place more limits in a txn than the min setting and 2) enforcing minLimitOrderAmountInBase both cannot be manipulated. Auditors should focus on breaking these assumptions, and we can focus on the viability of our DOS protection as a whole vs adding an admin cancel

Main invariants

Token Balance

For a given token (T) and all markets (M) it is either the base or quote asset of, the balance of the AccountManager.sol (AM) must be equal to:

(T's feesAccrued in AM) + (account balances of T in AM) + (all open orders in all Ms that are selling T, converted to quote amount if is that M's quote token)

Access Control

For functions guarded by an operator approval check, only the "account", or a caller who has been approved by the account for that operator role required should be able to call the function

All trusted roles in the protocol

All described roles are expected to be multi-signature wallets or automated smart contracts with on-chain risk parameters for the foreseeable future.

RoleDescription
MARKET_CREATORCan create CLOB markets
MAX_LIMITS_PER_TX_SETTERCan configure maximum limits per transaction of a CLOB
TICK_SIZE_SETTERCan configure the tick size of a CLOB
MIN_LIMIT_ORDER_AMOUNT_SETTERCan set the minimum limit order amount of a CLOB
FEE_TIER_SETTERCan set the spot account fee tiers
MAX_LIMITS_EXEMPT_SETTERCan configure the accounts that are exempt from maximum limits
Owner (CLOBManager)All of the above capabilities
FEE_COLLECTOR / Owner (AccountManager)Can collect accrued fees

Running tests

The codebase utilizes the forge framework for compiling its contracts and executing tests coded in Solidity.

Prerequisites

  • forge (1.2.3-stable tested)

Setup

Once the above prerequisite has been successfully installed, the following commands can be executed to setup the repository:

git clone https://github.com/code-423n4/2025-07-gte-clob cd 2025-07-gte-clob

Tests

To run tests, the forge test command should be executed:

forge test

Coverage

Coverage can be executed via the built-in coverage command of forge (IR minimum is required):

FOUNDRY_PROFILE=coverage forge coverage --ir-minimum --report lcov
FileCoverage (Line / Function / Branch)
contracts/account-manager/AccountManager.sol92.1% / 90.0% / 87.5%
contracts/clob/CLOB.sol96.2% / 90.6% / 84.5%
contracts/clob/CLOBManager.sol92.0% / 89.5% / 80.0%
contracts/clob/types/Book.sol93.7% / 100.0% / 82.8%
contracts/clob/types/FeeData.sol97.1% / 100.0% / 0.0%
contracts/clob/types/Order.sol100.0% / 100.0% / 0.0%
contracts/clob/types/RedBlackTree.sol100.0% / 100.0% / 0.0%
contracts/clob/types/TransientMakerData.sol36.8% / 100.0% / 33.3%
contracts/router/GTERouter.sol88.4% / 75.0% / 66.7%
contracts/utils/Operator.sol94.1% / 100.0% / 100.0%
contracts/utils/types/EventNonce.sol88.9% / 100.0% / 100.0%
contracts/utils/types/OperatorHelperLib.sol28.6% / 50.0% / 0.0%
Totals83.9% / 91.2% / 52.9%

Creating a PoC

The project is composed of three core systems; the CLOB system, the AccountManager contract, and the GTERouter contract. Within the codebase, we have introduced a PoC.t.sol test file under the test/c4-poc folder that sets up each system with mock implementations to allow PoCs to be constructed in a straightforward manner.

Specifically, we combined the logic of the RouterTestBase.t.sol and CLOBTestBase.sol files manually to combine the underlying deployments.

Depending on where the vulnerability lies, the PoC should utilize the relevant storage entries (i.e. the router in case a router vulnerability is demonstrated etc.).

For a submission to be considered valid, the test case should execute successfully via the following command:

forge test --match-test submissionValidity

Miscellaneous

Employees of GTE and employees' family members are ineligible to participate in this audit.

Code4rena's rules cannot be overridden by the contents of this README. In case of doubt, please check with C4 staff.