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, executeClobPostFillOrder or executeUniV2SwapExactTokensForTokens.

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 a sufficient amount of tokens to provide them for the call.

    • Impact: The amount of the tokenIn token will be provided for this call or will be used from the caller account in the clobFactory.

  • 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 clobFactory.

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

  • An unsupported function selector is provided for the execution.

  • The result is less than amountOutMin.

  • Invalid CLOB address

Function call analysis

  • this._handleWrap(tokenIn, amountIn, settlement)

    • What is controllable? tokenIn, amountIn, and settlement.

    • If the return value is controllable, how is it used and how can it go wrong? Returns isWrapping equal to true, in the case when the caller provides nonzero msg.value and token is zero, it means that provided msg.value has been deposited to the weth contract and weth should be used as an input-token address. Otherwise, it will return the token itself and false.

    • What happens if it reverts, reenters or does other unusual control flow? Reverts if the caller has provided nonzero msg.value and nonzero token address and also if msg.value is not equal to the amountIn or settlement is ACCOUNT.

  • this._handleWrap(tokenIn, amountIn, settlement) -> this.weth.deposit{value: msg.value}

    • What is controllable? N/A.

    • If the return value is controllable, how is it used and how can it go wrong? This function does not return a value.

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

  • SafeTransferLib.safeApprove(address(this.weth), address(this.clobFactory), amountIn)

    • What is controllable? amountIn.

    • If the return value is controllable, how is it used and how can it go wrong? This function does not return a value.

    • What happens if it reverts, reenters or does other unusual control flow? There are no problems here. This function is used for the case isWrapping == true, when the funds inside the deposit function will be transferred from the router contract instead of the caller.

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

    • What is controllable? tokenIn and amountIn.

    • If the return value is controllable, how is it used and how can it go wrong? This function does not return a value.

    • What happens if it reverts, reenters or does other unusual control flow? The caller should set up the router contract address as an allowed operator to execute this function.

  • 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? This function does not return a value.

    • What happens if it reverts, reenters or does other unusual control flow? Reverts if the allowance is not enough.

  • 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? This function does not return a value.

    • What happens if it reverts, reenters or does other unusual control flow? Reverts if the router is not an allowed operator or if the balance of the caller is not enough to withdraw amountIn tokens.

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

    • What is controllable? N/A.

    • If the return value is controllable, how is it used and how can it go wrong? This function does not return a value.

    • What happens if it reverts, reenters or does other unusual control flow? This function is called in the case when this is not a first execution and the previous has been executeUniV2SwapExactTokensForTokens, so the result of the previous swap should be deposited to the clobFactory. There are no problems here.

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

    • What is controllable? N/A.

    • If the return value is controllable, how is it used and how can it go wrong? This function does not return a value.

    • What happens if it reverts, reenters or does other unusual control flow? This function is called to deposit to the clobFactory the result of the previous swap. There are no problems here.

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

    • What is controllable? args (excluding amount and settlement).

    • If the return value is controllable, how is it used and how can it go wrong? Returns the result of the order fill.

    • What happens if it reverts, reenters or does other unusual control flow? Reverts if the order type is FILL_OR_KILL, but it was not fully filled, or if the provided price is incorrect.

  • this._executeClobPostFillOrder(route, hops[i]) -> 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? This function does not return a value.

    • What happens if it reverts, reenters or does other unusual control flow? Withdraws funds from the clobFactory on behalf of the router to continue execution for the executeUniV2SwapExactTokensForTokens case.

  • this._executeClobPostFillOrder(route, hops[i]) -> 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? This function does not return a value.

    • What happens if it reverts, reenters or does other unusual control flow? Withdraws the resulting tokens to the caller from the clobFactory at the final step of the execution, in the case Settlement == INSTANT.

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

    • What is controllable? path[0] and amountIn.

    • If the return value is controllable, how is it used and how can it go wrong? This function does not return a value.

    • 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, path, and amountIn (only in the case of the first execution).

    • If the return value is controllable, how is it used and how can it go wrong? Returns the results of the swap.

    • What happens if it reverts, reenters or does other unusual control flow? Reverts if the result of the swap is less than amountOutMin.

  • this._handleUnwrap(route.prevAmountOut) -> weth.withdraw(amount)

    • What is controllable? N/A.

    • If the return value is controllable, how is it used and how can it go wrong? This function does not return a value.

    • What happens if it reverts, reenters or does other unusual control flow? Reverts if the balance of the router is less than the requested amount.

Zellic © 2025Back to top ↑