Float Funding Rate

December 1, 2021

1. Preface

The team of Float contracted byterocket to conduct a smart contract audit of the funding rate feature, which is being added to their smart contracts. Float is a  “peer-to-peer, yield-enhanced, floating synthetic asset exposure mechanism”. They describe themselves as “the easiest and safest way for users to buy synthetic assets. Users do not need to worry about over-collateralization, or suddenly getting liquidated”.

Their smart contracts are being updated to include the feature of a funding rate, which aims to restore the balance of heavily unbalanced markets via payments. In practice, the system will constantly shift liquidity from the overbalanced to the underbalanced side of the market.

The functionality is contained in the LongShort.sol  and Staker.sol files. During this audit, we only focused on changes that have been made because of this new feature.

The team of byterocket reviewed and audited the above smart contracts in the course of this audit. We facilitated the audit on November 30th and December 1st, 2021.

  • Manual Multi-Pass Code Review
  • In-Depth Protocol Analysis
  • Automated Code Review
  • Formal Report

byterocket gained access to the code via their public GitHub repository. We based the audit on the master branch’s state from November 27th, 2021 (commit hash d68bd0acf80ff45f322b251c2eef500f3679ab8d).

2. Manual Code Review

We conducted a manual multi-pass code review of the smart contracts mentioned in section (1). Three different people went through the smart contract independently and compared their results in multiple concluding discussions.

These contracts are written according to the latest standards used within the Ethereum community and the Solidity community’s best practices. The naming of variables is very logical and understandable, which results in the contract being useful to understand. The code is very well documented and up to the latest standards.

Due to the very structured and open process that is being used for contract development at Float, it was very easy for us to gain insights in certain motivations and ideas behind the changes and implementations. Additionally, the team is working on the forefront of novel testing methods and techniques for smart contracts, which also made this a very pleasant endeavor for us.

On the code level, we found no bugs or flaws. A further check with multiple automated reviewing tools (MythX, Slither, Manticore, and different fuzzing tools) did not find any additional bugs.

3. Protocol/Logic Review

Part of our audits are also analyses of the protocol and its logic. A team of three auditors went through the implementation and documentation of the implemented feature change.

We went through all of the provided documentation, tests and contracts in a very detailed manner. The general description of the feature and the protocol itself is very well made, it’s very easy to understand how each function is supposed to work and what it implements.

We were not able to discover any problems in the protocol implemented in the smart contract.

3.1 Feature implementation

The feature implementation itself is pretty straightforward. First, there is a function in LongShort.sol that allows the new fundingRateMultiplier to be set by an admin account. This is either a multi-sig or (later on) a DAO.

function changeMarketFundingRateMultiplier(uint32 marketIndex, uint256 _fundingRateMultiplier_e18) external adminOnly {
 require(_fundingRateMultiplier_e18 >= 5e16 &&  _fundingRateMultiplier_e18 <= 5e19, "not in range: 5% <= funding rate <= 5000%");
 fundingRateMultiplier_e18[marketIndex] = _fundingRateMultiplier_e18;
 emit MarketFundingRateMultiplerChanged(marketIndex, _fundingRateMultiplier_e18);
}

This function sufficiently checks whether the provided access right is ensured (adminOnly) and also verifies whether the input _fundingRateMultiplier_e18 is within reasonable bounds.

The next interesting function _calculateFundingAmount()  is then used to determine the actual amount that is being shifted between the over- and underbalanced side of the market.

function _calculateFundingAmount(
   uint32 marketIndex,
   uint256 _fundingRateMultiplier_e18,
   uint256 overbalancedValue,
   uint256 underbalancedValue
 ) internal virtual returns (uint256 fundingAmount) {
 (uint256 lastUpdateTimestamp, , ) =  
 IStaker(staker).accumulativeFloatPerSyntheticTokenSnapshots(
   marketIndex,
   marketUpdateIndex[marketIndex]
 );

 fundingAmount = ((overbalancedValue - underbalancedValue) *
                 _fundingRateMultiplier_e18 *
                 (block.timestamp - lastUpdateTimestamp)) /
                 SECONDS_IN_A_YEAR_e18;
 }

Lastly, the corresponding funding amount is then used during the rebalancing of markets in LongShort.sol in line 750 to 763.

uint256 fundingRateMultiplier = fundingRateMultiplier_e18[marketIndex];
if (fundingRateMultiplier > 0) {
 if (longValue < shortValue) {
   valueChange +=
   int256(_calculateFundingAmount(marketIndex, fundingRateMultiplier,
          shortValue, longValue);
 } else {
   valueChange -=
   int256(_calculateFundingAmount(marketIndex, fundingRateMultiplier,
          longValue, shortValue));
 }
}

Since some of the necessary actions have (so far) only been facilitated during shifts (moving tokens from long to short or vice versa without withdrawing them from the market), a lot of functions have been renamed from “...Shift” to “...Action”.

Throughout the implementation of this feature, we have not found any logical errors.

4. Summary

During our code review (which was done manually and automated), we found no bugs or flaws. Our automated systems and review tools also did not find any additional ones.

The protocol review and analysis did neither uncover any game-theoretical nature problems nor any other functions prone to abuse. We have not found any logical errors in the implementation.

In general, we are delighted with the overall quality of the code and its documentation. Additionally, there are extensive tests and even a custom testing framework, covering all of the functionality of the system.

Disclaimer

As of the date of publication, the information provided in this report reflects the presently held understanding of the auditor’s knowledge of security patterns as they relate to the client’s contract(s), assuming that blockchain technologies, in particular, will continue to undergo frequent and ongoing development and therefore introduce unknown technical risks and flaws. The scope of the audit presented here is limited to the issues identified in the preliminary section and discussed in more detail in subsequent sections. The audit report does not address or provide opinions on any security aspects of the Solidity compiler, the tools used in the development of the contracts or the blockchain technologies themselves, or any issues not specifically addressed in this audit report.
The audit report makes no statements or warranties about the utility of the code, safety of the code, suitability of the business model, investment advice, endorsement of the platform or its products, the legal framework for the business model, or any other statements about the suitability of the contracts for a particular purpose, or their bug-free status.

To the full extent permissible by applicable law, the auditors disclaim all warranties, express or implied. The information in this report is provided “as is” without warranty, representation, or guarantee of any kind, including the accuracy of the information provided. The auditors hereby disclaim, and each client or user of this audit report hereby waives, releases and holds all auditors harmless from, any and all liability, damage, expense, or harm (actual, threatened, or claimed) from such use.

Stored on IPFS

We store our public audit reports on IPFS; a peer-to-peer network called the "Inter Planetary File System". This allows us to store our reports in a distributed network instead of just a single server, so even if our website is down, every report is still available.

Learn more about IPFS
Signed On-Chain

The IPFS Hash, a unique identifier of the report, is signed on-chain by both the client and us to prove that both sides have approved this audit report. This signing mechanism allows users to verify that neither side has faked or tampered with the audit.

Check the Signatures