TripleFi - Smart Contract Audit Report

Audit Summary

Hedgex Audit Report Triple.Fi is building a new ERC-20 token and derivatives platform.

For this audit, we reviewed TripleFi's HedgexSingle, HedgexERC20, LinkIndexPrice, and TripleIndexPrice contracts at commit ea59851c4c7f88c66d38e50326a28f50a3577bff on the team's GitHub repository.

Audit Findings

Please ensure trust in the team prior to investing as they have substantial control in the ecosystem.
Date: February 9th, 2022.

Finding #1 - HedgexSingle, LinkIndexPrice - Informational

Description: Several functions are declared public, but are never called internally.
			
- HedgexSingle: openLong, openShort, closeLong, closeShort, explosive, detectSlide, explosivePool, forceCloseAccount
- TripleIndexPrice: postPrice
Recommendation: We recommend declaring these functions external for additional gas savings on each call.

Contracts Overview

  • Users can utilize the HedgexSingle contract to open long and short positions on a margin token designated by the team.
  • The contract's derivative functionality starts when the total supply of the margin tokens stored in the contract reaches the minimum pool amount.
  • Users are minted $HEXS tokens when providing margin tokens to the contract for liquidity. Users receive an equal amount of $HEXS tokens for their margin tokens until the minimum pool value has been reached.
  • Once the minimum pool value has been reached, users receive a calculated amount of $HEXS tokens based on the total supply and calculated total value when providing liquidity.
  • Users can remove liquidity from the pool only in amounts less than the liquidity withdrawal limitation. The liquidity withdrawal limitation is based on the difference between the pool's net price and the calculated used margin.
  • The used margin amount for removing liquidity is dependent on the positive net position amount, current price index, and pool's net position rate limitation.
  • Users' $HEXS tokens are burned in an amount equal to the withdrawals of their margin token liquidity.

  • Users can open long and short positions on the margin token within the confines of the trade limitation amount, calculated position price range, and the net position rate limitation of the pool.
  • The opening trade limitation amount is dependent on the pool's net value, current index price, and open position limitation rate which is by default set to 3%.
  • The calculated position price range is calculated based on the current index price and sliding price rate.
  • The net position rate limitation of the pool can be updated by the team, but by default is set to 400,000.
  • Users can close long and short positions on the margin token within the confines of the trade limitation amount, calculated position price range, and the net position rate limitation of the pool.
  • The closing trade limitation amount is dependent on the pool's net value, current index price, and closing position limitation rate which is by default set to 10%.
  • There is a default fee rate of 0.06% when opening or closing any positions. 25% of the collected fees are set aside for the team while the team fee is toggled on and the remaining amount is added to the total pool amount.

  • Anyone can transfer a portion of another address's profit margin to their own address while the target address's "keep margin" amount surpasses their own account net value. 20% is transferred from the target address to the caller and the remainder is added to the total pool amount.
  • The target address's keep margin value is calculated based on the value of their short and long position value divided by the keep margin scale value which is set by the team.
  • Any user can "recharge" their available margin by providing more margin tokens to the contract in order to open further positions.
  • Any user can withdraw their available margin tokens only in amounts equal to the maximum margin withdrawal amount or less.
  • The users' maximum margin withdrawal amount is dependent on the calculated net value of their positions and their current used margin amount already in use.
  • Users' used margin amount is calculated based on the value of their short and long position value divided by the leverage amount which is set by the team upon deployment.
  • The price of the margin token is dependent on the "feedPrice" address. The LinkIndexPrice contract can be used as the address upon deployment and can use Chainlink price feeds to pull aggregated data from off-chain.
  • The TripleIndexPrice contract can be used to update the feedprice and decimal values. This contract relies on off-chain logic provided by the team.
  • Anyone can trigger the interest calculation process for another user which calculates the interest accrued from their positions. The interest amount is deducted from the target address's margin amount. The caller receives 10% of the interest amount and the remaining portion is collected as fees. This can only be performed within the first 5 minutes of each day.
  • The interest rate is dependent on the user's long/short positions, the pool's collective long/short positions, and the daily interest rate; set to 0.1% by default.

  • The pool's status can be set to liquidation once the profit margin amount reaches the pool's net value. Toggling the status of the pool to liquidation sets a new reduced index price.
  • After the pool's status has been toggled, any user can "force close" another user's account. Force closing a user's account clears their positions and transfers their rewards to an address provided by the caller. Users' reward amounts are calculated using the reduced index price.

  • The owner is granted the Contract Setter role upon deployment.
  • The Contract Setter role can set the pool net amount rate limit to any value at any time.
  • The Contract Setter role can set the pool net amount rate limit price to any value at any time.
  • The Contract Setter role can set the margin scale to any value at any time.
  • The Contract Setter can toggle short and long position functionality.
  • The Contract Setter can toggle and set the fee rate to any value at any time.
  • The Contract Setter can set the fee address at any time.
  • The fee address can withdraw the fee amount stored in the contract at any time.
  • The Contract Setter role can be transferred to any address at any time.
  • The team must operate off-chain logic to determine the current index price.
  • The LinkIndexPrice contract utilizes a Chainlink price feed in order to determine the price of the margin token. By doing so, the contract mitigates the risk of flash loan/price manipulation attacks.
  • These contracts are developed with Solidity 0.8.x, so they are protected from overflow/underflow attacks.
  • The logic is well structured to prevent re-entrancy issues in applicable functions.

External Threat Results

Vulnerability CategoryNotesResult
Arbitrary Storage WriteN/APASS
Arbitrary JumpN/APASS
Centralization of ControlThe team maintains the ownership controls described above.WARNING
Delegate Call to Untrusted ContractN/APASS
Dependence on Predictable VariablesN/APASS
Deprecated OpcodesN/APASS
Ether ThiefN/APASS
ExceptionsN/APASS
External CallsN/APASS
Flash LoansN/APASS
Integer Over/UnderflowN/APASS
Logical IssuesN/APASS
Multiple SendsN/APASS
OraclesN/APASS
SuicideN/APASS
State Change External CallsN/APASS
Unchecked RetvalN/APASS
User Supplied AssertionN/APASS
Critical Solidity CompilerN/APASS
Overall Contract Safety PASS

HedgexSingle Contract

 Token Graph

Multi-file Token

		
($) = payable function
 # = non-constant function		
							
 + [Int] IIndexPrice 
    - [Ext] indexPrice
    - [Ext] decimals #

 + [Int] IERC20 
    - [Ext] name
    - [Ext] symbol
    - [Ext] decimals
    - [Ext] totalSupply
    - [Ext] balanceOf
    - [Ext] allowance
    - [Ext] approve #
    - [Ext] transfer #
    - [Ext] transferFrom #

 + [Lib] TransferHelper 
    - [Int] safeApprove #
    - [Int] safeTransfer #
    - [Int] safeTransferFrom #

 +  HedgexERC20 (IERC20)
    - [Pub] Constructor #
    - [Int] _mint #
    - [Int] _burn #
    - [Prv] _approve #
    - [Prv] _transfer #
    - [Ext] approve #
    - [Ext] transfer #
    - [Ext] transferFrom #
    - [Ext] permit #

 +  HedgexSingle (HedgexERC20)
    - [Pub] Constructor #
       - modifiers: HedgexERC20
    - [Ext] addLiquidity #
    - [Ext] removeLiquidity #
    - [Pub] rechargeMargin #
    - [Ext] withdrawMargin #
    - [Pub] openLong #
       - modifiers: lock,ensure
    - [Pub] openShort #
       - modifiers: lock,ensure
    - [Pub] closeLong #
       - modifiers: lock,ensure
    - [Pub] closeShort #
       - modifiers: lock,ensure
    - [Pub] explosive #
       - modifiers: lock
    - [Pub] detectSlide #
       - modifiers: lock
    - [Pub] explosivePool #
       - modifiers: lock
    - [Pub] forceCloseAccount #
       - modifiers: lock
    - [Pub] getPoolNet
    - [Int] getPoolNet
    - [Int] poolLimitTrade
    - [Int] slideTradePrice
    - [Int] judegOpen #
    - [Int] feeCharge #
    - [Int] feeCharge #
    - [Int] getAccountNet
    - [Int] getAccountNet
    - [Ext] getPoolPosition
    - [Pub] getLatestPrice
    - [Ext] setFeedPrice #
    - [Ext] setPoolNetAmountRateLimitOpen #
    - [Ext] setPoolNetAmountRateLimitPrice #
    - [Ext] setKeepMarginScale #
    - [Ext] setCanAddLiquidity #
    - [Ext] setCanOpen #
    - [Ext] withdrawFee #
    - [Ext] setFeeOn #
    - [Ext] setFeeRate #
    - [Ext] setFeeTo #
    - [Ext] transferContractSetter #
    - [Ext] acceptContractSetter #

HedgexERC20 Contract

BEP20 Token Graph

Multi-file Token

												
($) = payable function
 # = non-constant function
 
 + [Int] IERC20 
    - [Ext] name
    - [Ext] symbol
    - [Ext] decimals
    - [Ext] totalSupply
    - [Ext] balanceOf
    - [Ext] allowance
    - [Ext] approve #
    - [Ext] transfer #
    - [Ext] transferFrom #

 +  HedgexERC20 (IERC20)
    - [Pub] Constructor #
    - [Int] _mint #
    - [Int] _burn #
    - [Prv] _approve #
    - [Prv] _transfer #
    - [Ext] approve #
    - [Ext] transfer #
    - [Ext] transferFrom #
    - [Ext] permit #
   

LinkIndexPrice Contract

BEP20 Token Graph

Multi-file Token

												
($) = payable function
 # = non-constant function
 
  + [Int] IIndexPrice 
    - [Ext] indexPrice
    - [Ext] decimals #

 + [Int] AggregatorV3Interface 
    - [Ext] decimals
    - [Ext] description
    - [Ext] version
    - [Ext] getRoundData
    - [Ext] latestRoundData

 +  LinkIndexPrice (IIndexPrice)
    - [Pub] Constructor #
    - [Ext] indexPrice

TripleIndexPrice Contract

BEP20 Token Graph

Multi-file Token

												
($) = payable function
 # = non-constant function
 
 + [Int] IIndexPrice 
    - [Ext] indexPrice
    - [Ext] decimals #

 +  TripleIndexPrice (IIndexPrice)
    - [Pub] Constructor #
    - [Pub] postPrice #
    - [Ext] indexPrice