Assessment reports>GTE>Threat Model>executeRoute

Function: executeRoute(address tokenIn, uint256 amountIn, uint256 amountOutMin, uint256 deadline, bytes[] hops, ICLOB.Settlement settlement)

This function allows to execute several actions, postFillOrder or swapExactTokensForTokens.

Inputs

  • tokenIn

    • Control: Full control.

    • Constraints: No constraints.

    • Impact: The address of the tokens that will be provided by the caller to execute the desired action.

  • amountIn

    • Control: Full control.

    • Constraints: The caller should own the sufficient amount of tokens to provide them for the call.

    • Impact: The amount of the tokenIn token will be provided for this call.

  • amountOutMin

    • Control: Full control.

    • Constraints: No constraints.

    • Impact: This amount is used for a slippage check at the end of the call.

  • deadline

    • Control: Full control.

    • Constraints: The block.timestamp cannot be more than the deadline.

    • Impact: The deadline for this call execution.

  • hops

    • Control: Full control.

    • Constraints: No constraints.

    • Impact: The hop-specific data.

  • settlement

    • Control: Full control.

    • Constraints: INSTANT or ACCOUNT.

    • Impact: Determines if settlement occurs with the caller's wallet or their account in CLOBManager.

Branches and code coverage

Intended branches

  • settlement is ICLOB.Settlement.INSTANT, and hops[0][0:4] is this.executeClobPostFillOrder.selector.

  • settlement is ICLOB.Settlement.ACCOUNT, and hops[0][0:4] is this.executeClobPostFillOrder.selector.

  • settlement is ICLOB.Settlement.INSTANT, and hops[0][0:4] is this.executeUniV2SwapExactTokensForTokens.selector.

  • settlement is ICLOB.Settlement.ACCOUNT, and hops[0][0:4] is this.executeUniV2SwapExactTokensForTokens.selector.

Negative behavior

  • Unsupported function selector is provided for the execution.

  • The result is less than amountOutMin.

Function call analysis

  • this.clobFactory.deposit(msg.sender, tokenIn, amountIn, False)

    • What is controllable? tokenIn and amountIn.

    • If the return value is controllable, how is it used and how can it go wrong? N/A.

    • What happens if it reverts, reenters or does other unusual control flow? Reverts if the caller has assigned insufficient approval for clobFactory or if the caller's balance is not enough to transfer amountIn.

  • SafeTransferLib.safeTransferFrom(tokenIn, msg.sender, address(this), amountIn)

    • What is controllable? tokenIn and amountIn.

    • If the return value is controllable, how is it used and how can it go wrong? N/A.

    • What happens if it reverts, reenters or does other unusual control flow? Reverts if the caller has assigned insufficient approval for this contract or if the caller's balance is not enough to transfer amountIn.

  • this.clobFactory.withdraw(msg.sender, tokenIn, amountIn, True)

    • What is controllable? tokenIn and amountIn.

    • If the return value is controllable, how is it used and how can it go wrong? N/A.

    • What happens if it reverts, reenters or does other unusual control flow? Reverts if msg.sender balance in the clobFactory is not enough to withdraw.

  • this._executeClobPostFillOrder(route, hops[i]) -> SafeTransferLib.safeApprove(route.nextTokenIn, address(this.clobFactory), route.prevAmountOut)

    • What is controllable? route.nextTokenIn.

    • If the return value is controllable, how is it used and how can it go wrong? N/A.

    • What happens if it reverts, reenters or does other unusual control flow? There are no problems here.

  • this._executeClobPostFillOrder(route, hops[i]) -> this.clobFactory.deposit(msg.sender, route.nextTokenIn, route.prevAmountOut, True)

    • What is controllable? route.nextTokenIn.

    • If the return value is controllable, how is it used and how can it go wrong? N/A.

    • What happens if it reverts, reenters or does other unusual control flow? This function is executed when it is not the first hop and the previous hop was not executeClobPostFillOrder.selector. This means that the contract retains the resulting tokens, which should be deposited into the clobFactory to make these funds available for the current hop execution.

  • this._executeClobPostFillOrder(route, hops[i]) -> this._getClobTokenOutAndBaseLotsIn(route.prevAmountOut, market, args) -> market.getQuoteToken()

    • What is controllable? market and args.

    • If the return value is controllable, how is it used and how can it go wrong? Returns the address of the Quote token from the specified market contract, which will be used as a tokenOut in the case of SELL.

    • What happens if it reverts, reenters or does other unusual control flow? There are no problems here.

  • this._executeClobPostFillOrder(route, hops[i]) -> this._getClobTokenOutAndBaseLotsIn(route.prevAmountOut, market, args) -> market.getBaseTokenAmountToBaseLots(amountIn)

    • What is controllable? market.

    • If the return value is controllable, how is it used and how can it go wrong? Returns amount / self.config.baseLotSize, which can be zero as a result of rounding down if amount is less than baseLotSize.

    • What happens if it reverts, reenters or does other unusual control flow? There are no problems here.

  • this._executeClobPostFillOrder(route, hops[i]) -> this._getClobTokenOutAndBaseLotsIn(route.prevAmountOut, market, args) -> market.getBaseToken()

    • What is controllable? market and args.

    • If the return value is controllable, how is it used and how can it go wrong? Returns the address of the BASE token from the specified market contract, which will be used as a tokenOut in the case of BUY.

    • What happens if it reverts, reenters or does other unusual control flow? There are no problems here.

  • this._executeClobPostFillOrder(route, hops[i]) -> this._getClobTokenOutAndBaseLotsIn(route.prevAmountOut, market, args) -> market.getQuoteTokenAmountToBaseLots(amountIn, args.priceInTicks)

    • What is controllable? market.

    • If the return value is controllable, how is it used and how can it go wrong? Returns (quoteAmount * self.config.baseLotsPerBaseUnit)/ (priceInTicks * self.config.tickSizeInQuoteLotsPerBaseUnit * self.config.quoteLotSize), which can be zero as a result of rounding down if quoteAmount * self.config.baseLotsPerBaseUnit is less than priceInTicks * self.config.tickSizeInQuoteLotsPerBaseUnit * self.config.quoteLotSize.

    • What happens if it reverts, reenters or does other unusual control flow? There are no problems here.

  • this._executeClobPostFillOrder(route, hops[i]) -> market.postFillOrder(msg.sender, args)

    • What is controllable? market and args.

    • If the return value is controllable, how is it used and how can it go wrong? if the resulting prevAmountOut is less than amountOutMin, the function reverts.

    • What happens if it reverts, reenters or does other unusual control flow? Reverts if the provided priceInTicks is invalid or if amountInBaseLots is less than MIN_FILL_ORDER_AMOUNT_BASE_LOTS. It also reverts if fillOrderType is FILL_OR_KILL but the order has not been fully filled.

  • this._executeClobPostFillOrder(route, hops[i]) -> this.clobFactory.withdraw(msg.sender, tokenOut, amountOutFilled, True)

    • What is controllable? N/A.

    • If the return value is controllable, how is it used and how can it go wrong? N/A.

    • What happens if it reverts, reenters or does other unusual control flow? This function executes in the middle hop when the next hop is not executeClobPostFillOrder.selector.

  • this._executeClobPostFillOrder(route, hops[i]) -> this.clobFactory.withdraw(msg.sender, tokenOut, amountOutFilled, False)

    • What is controllable? N/A.

    • If the return value is controllable, how is it used and how can it go wrong? N/A.

    • What happens if it reverts, reenters or does other unusual control flow? This function executes in the last hop when the settlement is INSTANT to transfer resulting tokens to the user.

  • this._executeUniV2SwapExactTokensForTokens(route, hops[i]) -> SafeTransferLib.safeApprove(path[0], address(this.uniV2Router), amountIn)

    • What is controllable? amountIn.

    • If the return value is controllable, how is it used and how can it go wrong? N/A.

    • What happens if it reverts, reenters or does other unusual control flow? There are no problems here.

  • this._executeUniV2SwapExactTokensForTokens(route, hops[i]) -> this.uniV2Router.swapExactTokensForTokens(amountIn, amountOutMin, path, recipient, block.timestamp)

    • What is controllable? amountOutMin and path.

    • If the return value is controllable, how is it used and how can it go wrong? The resulting amounts can be less than expected.

    • What happens if it reverts, reenters or does other unusual control flow? N/A.

Zellic © 2025Back to top ↑