Halborn Logo

THORSwap Aggregators - THORSwap


Prepared by:

Halborn Logo

HALBORN

Last Updated 04/26/2024

Date of Engagement by: April 1st, 2022 - April 17th, 2022

Summary

100% of all REPORTED Findings have been addressed

All findings

3

Critical

0

High

0

Medium

0

Low

2

Informational

1


1. INTRODUCTION

THORSwap engaged Halborn to conduct a security audit on their Aggregator smart contracts beginning on April 1st, 2022 and ending on April 17th, 2022. The security assessment was scoped to the Aggregator and vTHOR smart contracts provided in the exchange-contracts GitHub repository thorswap/thorswap-contract-v2.

2. AUDIT SUMMARY

The team at Halborn was provided two weeks for the engagement and assigned one full-time security engineer to audit the security of the smart contract. The security engineer is a blockchain and smart-contract security expert with advanced penetration testing, smart-contract hacking, and deep knowledge of multiple blockchain protocols.

The purpose of this audit is to:

    • Ensure that smart contract functions operate as intended

    • Identify potential security issues with the smart contracts

In summary, Halborn identified few security risks that were mostly addressed by the THORSwap team.

3. TEST APPROACH & METHODOLOGY

Halborn performed a combination of manual and automated security testing to balance efficiency, timeliness, practicality, and accuracy in regard to the scope of this audit. While manual testing is recommended to uncover flaws in logic, process, and implementation; automated testing techniques help enhance coverage of the bridge code and can quickly identify items that do not follow security best practices. The following phases and associated tools were used throughout the term of the audit:

    • Research into architecture and purpose

    • Smart contract manual code review and walkthrough

    • Graphing out functionality and contract logic/connectivity/functions (solgraph)

    • Manual assessment of use and safety for the critical Solidity variables and functions in scope to identify any arithmetic related vulnerability classes

    • Manual testing by custom scripts

    • Scanning of solidity files for vulnerabilities, security hotspots or bugs. (MythX)

    • Static Analysis of security for scoped contract, and imported functions. (Slither)

    • Testnet deployment (Brownie, Remix IDE)

4. SCOPE

IN-SCOPE: The security assessment was scoped to the following smart contracts:

    • TSAggregator.sol

    • TSAggregator2LegUniswapV2.sol

    • TSAggregator2LegUniswapV3.sol

    • TSAggregatorGeneric.sol

    • TSAggregatorTokenTransferProxy.sol

    • TSAggregatorUniswapV2.sol

    • TSAggregatorUniswapV3.sol

    • vTHOR.sol

Audited Commit ID:

Fixed Commit ID:

5. RISK METHODOLOGY

Vulnerabilities or issues observed by Halborn are ranked based on the risk assessment methodology by measuring the LIKELIHOOD of a security incident and the IMPACT should an incident occur. This framework works for communicating the characteristics and impacts of technology vulnerabilities. The quantitative model ensures repeatable and accurate measurement while enabling users to see the underlying vulnerability characteristics that were used to generate the Risk scores. For every vulnerability, a risk level will be calculated on a scale of 5 to 1 with 5 being the highest likelihood or impact.
RISK SCALE - LIKELIHOOD
  • 5 - Almost certain an incident will occur.
  • 4 - High probability of an incident occurring.
  • 3 - Potential of a security incident in the long term.
  • 2 - Low probability of an incident occurring.
  • 1 - Very unlikely issue will cause an incident.
RISK SCALE - IMPACT
  • 5 - May cause devastating and unrecoverable impact or loss.
  • 4 - May cause a significant level of impact or loss.
  • 3 - May cause a partial impact or loss to many.
  • 2 - May cause temporary impact or loss.
  • 1 - May cause minimal or un-noticeable impact.
The risk level is then calculated using a sum of these two values, creating a value of 10 to 1 with 10 being the highest level of security risk.
Critical
High
Medium
Low
Informational
  • 10 - CRITICAL
  • 9 - 8 - HIGH
  • 7 - 6 - MEDIUM
  • 5 - 4 - LOW
  • 3 - 1 - VERY LOW AND INFORMATIONAL

6. SCOPE

Out-of-Scope: New features/implementations after the remediation commit IDs.

7. Assessment Summary & Findings Overview

Critical

0

High

0

Medium

0

Low

2

Informational

1

Impact x Likelihood

HAL-01

HAL-02

HAL-03

Security analysisRisk levelRemediation Date
INITIAL vTHOR SHARE PRICE MANIPULATION EXPOSURELowRisk Accepted
MISSING RE-ENTRANCY PROTECTIONLowSolved - 04/21/2022
POSSIBLE MISUSE OF PUBLIC FUNCTIONSInformationalSolved - 04/21/2022

8. Findings & Tech Details

8.1 INITIAL vTHOR SHARE PRICE MANIPULATION EXPOSURE

// Low

Description

After deployment, the vTHOR contract is initialed without seeding liquidity, exposing the vault to share price manipulation attacks.

  1. The vTHOR contract is deployed by the THORSwap team.
  2. An attacker finds the vTHOR contract before anyone can deposit their tokens.
  3. The attacker deposits 1 token, for which they receive 1 share. This transaction sets the share price at 1 token/share.
  4. The attacker then transfers an additional 999 tokens to the vTHOR contract. This transaction increases the share price to 1000 tokens/share.
  5. A victim user finds the vTHOR contract and deposits 1500 tokens. Due to the integer rounding, the user only receives 1 share. This transaction modifies the share price to 1250 tokens/share.
  6. The attacker then, withdraws from the contract using the redeem function. Depending on the distribution of shares, they will receive 1250 tokens, of which 250 will belong to the victim user.

We note that the impact and likelihood of the vulnerability are low because the attacker has limited opportunity to exploit the issue. However, contract developers must be aware of the initial exposure to prevent potential damage.

Score
Impact: 3
Likelihood: 1
Recommendation

RISK ACCEPTED: The THORSwap team accept the risk of this finding and will deploy vTHOR and deposit THOR from treasury first to mitigate the issue.

8.2 MISSING RE-ENTRANCY PROTECTION

// Low

Description

The vTHOR contract missed the nonReentrant guard in the deposit, mint, withdraw and redeem public functions. Even if the functions follow the check-effects-interactions pattern, we recommend using a mutex to be protected against cross-function reentrancy attacks. By using this lock, an attacker can no longer exploit the function with a recursive call.

Note that the vTHOR contract included a mutex implementation called ReentrancyGuard, which provides a modifier to any function called nonReentrant that guards with a mutex against reentrancy attacks. However, the modifier is not used within the contract.

Code Location

vTHOR.sol

function deposit(uint256 assets, address receiver) public returns (uint256 shares) {
    // Check for rounding error since we round down in previewDeposit.
    require((shares = previewDeposit(assets)) != 0, "ZERO_SHARES");
    // Need to transfer before minting or ERC777s could reenter.
    address(_asset).safeTransferFrom(msg.sender, address(this), assets);
    _mint(receiver, shares);
    emit Deposit(msg.sender, receiver, assets, shares);
}

function mint(uint256 shares, address receiver) public returns (uint256 assets) {
    assets = previewMint(shares); // No need to check for rounding error, previewMint rounds up.
    // Need to transfer before minting or ERC777s could reenter.
    address(_asset).safeTransferFrom(msg.sender, address(this), assets);
    _mint(receiver, shares);
    emit Deposit(msg.sender, receiver, assets, shares);
}

function withdraw(
    uint256 assets,
    address receiver,
    address owner
) public returns (uint256 shares) {
    shares = previewWithdraw(assets); // No need to check for rounding error, previewWithdraw rounds up.
    if (msg.sender != owner) {
        uint256 allowed = allowance[owner][msg.sender]; // Saves gas for limited approvals.
        if (allowed != type(uint256).max) allowance[owner][msg.sender] = allowed - shares;
    }
    _burn(owner, shares);
    emit Withdraw(msg.sender, receiver, owner, assets, shares);
    address(_asset).safeTransfer(receiver, assets);
}

function redeem(
    uint256 shares,
    address receiver,
    address owner
) public returns (uint256 assets) {
    if (msg.sender != owner) {
        uint256 allowed = allowance[owner][msg.sender]; // Saves gas for limited approvals.
        if (allowed != type(uint256).max) allowance[owner][msg.sender] = allowed - shares;
    }
    // Check for rounding error since we round down in previewRedeem.
    require((assets = previewRedeem(shares)) != 0, "ZERO_ASSETS");
    _burn(owner, shares);
    emit Withdraw(msg.sender, receiver, owner, assets, shares);
    address(_asset).safeTransfer(receiver, assets);
}
Score
Impact: 3
Likelihood: 1
Recommendation

SOLVED: The THORSwap team added the nonReentrant modifier to the deposit, mint, withdraw and redeem functions.

8.3 POSSIBLE MISUSE OF PUBLIC FUNCTIONS

// Informational

Description

In the Owners and TSAggregator contracts there are management functions marked as public, but they are never directly called within the contract itself or in any of its descendants:

  • setOwner(address owner, bool active) public virtual isOwner (Owners.sol#19)
  • setFee(uint256 _fee, address _feeRecipient) public (TSAggregator.sol#26)
Score
Impact: 1
Likelihood: 1
Recommendation

SOLVED: The THORSwap team marked the setOwner and setFee functions as external.

9. Automated Testing

STATIC ANALYSIS REPORT

Description

Halborn used automated testing techniques to enhance coverage of certain areas of the scoped contract. Among the tools used was Slither, a Solidity static analysis framework. After Halborn verified all the contracts in the repository and was able to compile them correctly into their abi and binary formats. This tool can statically verify mathematical relationships between Solidity variables to detect invalid or inconsistent usage of the contracts' APIs across the entire code-base.

Slither Results

TSAggregator.sol

TSAggregator2LegUniswapV2.sol

TSAggregator2LegUniswapV3.sol

TSAggregatorGeneric.sol

TSAggregatorTokenTransferProxy.sol

TSAggregatorUniswapV2.sol

TSAggregatorUniswapV3.sol

vTHOR.sol

  • No major issues found by Slither.

  • The authorization (use of tx.origin) and "send eth to arbitrary user" issues are all false positives.

AUTOMATED SECURITY SCAN

MYTHX

Halborn used automated security scanners to assist with detecting well-known security issues and to identify low-hanging fruits on the targets for this engagement. MythX, a security analysis service for Ethereum smart contracts, is among the tools used. MythX was used to scan all the contracts and sent the compiled results to the analyzers to locate any vulnerabilities.

Results

TSAggregator2LegUniswapV2.sol

TSAggregator2LegUniswapV3.sol

TSAggregatorTokenTransferProxy.sol

TSAggregatorUniswapV2.sol

TSAggregatorUniswapV3.sol

ReentrancyGuard.sol

SafeTransferLib.sol

  • No major issues found by MythX.

  • The reentrancy, authorization, DOS and requirement violation issues are all false positives.

Halborn strongly recommends conducting a follow-up assessment of the project either within six months or immediately following any material changes to the codebase, whichever comes first. This approach is crucial for maintaining the project’s integrity and addressing potential vulnerabilities introduced by code modifications.

© Halborn 2024. All rights reserved.