Defira

Smart Contract Audit Report

Audit Summary

Defira Audit Report Defira is building a new decentralized automated liquidity protocol trading platform that is used to exchange cryptocurrencies, with additional contracts offering the ability to stake for rewards.

For this audit, we reviewed Defira's contracts using code provided by the project team.

Audit Findings

Please ensure trust in the team prior to investing as they have substantial control in the ecosystem.
Date: March 11th, 2022.
Updated: March 14th, 2022 to document the project team's response to Finding #1.

Finding #1 - SealedFiraUnlocker - Low

Description: A user's deposits are stored in the order that they were deposited in, and are unlocked in this same order. If a user deposits, then the contract's lock duration is shortened, then the user deposits again, they will have to wait until their original deposit has unlocked before redeeming any rewards.
Reproduction Steps:
  1. The lock duration is set to 30 days.
  2. A user locks 50 tokens.
  3. The lock duration is set to 1 day.
  4. The user locks 50 more tokens.
  5. 1 day passes and the user attempts to redeem rewards for the second 50 token deposit, but it fails. The user will have to wait 30 days in order to redeem rewards from both deposits.
Risk/Impact: In some instances, users will have to wait longer than intended to redeem rewards from deposits.
Recommendation: The logic in the updateExpiredLocks() function should be updated to support changes in lock duration, or the team should exercise caution when shortening the lock duration.
Update: The team acknowledges this issue and states that they have no plans to shorten the lock duration in this contract.

Finding #2 - FarmController & SealedFira - Informational

Description: The following functions are declared public, but are never called internally:
FarmController.sendReserveToPools(), SealedFira.setTransferAllowed(), SealedFira.setAllTransfersAllowed().
Recommendation: These functions can be declared external for additional gas savings on each call.

Contracts Overview

UniswapV2ERC20 Contract:
  • The UniswapV2ERC20 contract implements the ERC20 standard for use as an LP token.
  • This contract utilizes a "permit" mechanism which allows the owner of the $TRANQ-LP tokens to sign a transaction that enables another user to withdraw tokens and send them to the recipient. The recipient then submits the permit on behalf of the owner.
UniswapV2Factory Contract:
  • The UniswapV2Factory contract is responsible for the creation of liquidity pairs for two tokens, thereby enabling trading on the platform.
  • When creating a new trading pair, the UniSwapV2Pair initialize() function is called which allows the factory to specify the two ERC20 tokens that this pair will exchange.
  • Once the pool is created, its address is stored with a double mapping that takes both token addresses as input.
  • The "fee setter" address has the ability to update any UniswapPair's swap fee at any time through this contract.
  • The fee setter can update its own address at any time.
UniswapV2Pair Contract:
  • The UniswapV2Pair contract is the core Uniswap trading functionality.
  • Each UniswapV2Pair manages a liquidity pool made up of reserves of two ERC-20 tokens.
  • This contract is responsible for tracking the balance of both tokens in the pair, as well as mints and burns of the LP token.
  • Users can add liquidity by providing an equivalent value of each token and are minted an LP token in return. The LP tokens may be burned to receive the underlying assets at any time.
  • Users may also exchange one token for an equivalent amount of the other token based on the current market value.
  • A swap fee, which is defaulted to 0.3%, is taken on an exchange between tokens and given as rewards to LP providers.
  • Of the fee collected, half is taken on liquidity adds and burns and sent to a "feeTo" address.
  • The UniswapV2Factory address has the ability to update the swap fee to up to 100% at any time.
UniswapV2Router02 Contract:
  • The UniswapV2Router02 contract is used to interact with liquidity pools that are created via the UniswapV2Factory contract.
  • UniswapV2Router02 routes orders to the user-determined pair contract to swap assets.
  • This contract performs requirement checks needed for swapping tokens, adding liquidity, and removing liquidity.
SealedFira Contract:
  • Sealed Fira is an ERC-20 token with some additional ownership controls.
  • Authorized users can mint any amount of $sFIRA tokens to any address at any time.
  • The owner has the ability to add or remove any address from the list of authorized users at any time.
  • The owner can disable transfers at any time; only transfers involving a Whitelisted address are permitted while transfers are disabled.
  • The owner can add or remove any address from the Whitelist at any time.
Fira Contract:
  • Fira tokens are used to represent votes intended to be used in a DAO where one token represents one vote.
  • Any authorized user can mint any amount of tokens to any address at any time.
  • A maximum allowed supply exists; however, any authorized user can update the maximum allowed supply at any time.
  • Users cannot transfer over the maximum transfer amount at once unless either the sender or recipient is excluded from anti-whale logic.
  • Users may delegate their votes to another address allowing them to vote on behalf of the user.
  • Once votes are delegated, the user must explicitly delegate back to themselves to regain their votes.
  • Users also have the option to delegate through the use of a signed message, allowing for a gasless delegation for the user.
  • The owner can exclude any address from anti-whale logic at any time.
  • The owner can update the maximum transfer amount at any amount at any time.
FiraCirculatingSupply Contract:
  • This contract is used to calculate the circulating supply of a specified token.
  • When calculating circulating supply, the balances of specified "non-circulating" addresses are subtracted from the total supply.
  • The owner can add or remove any address from the non-circulating address list at any time.
  • The owner can update the token at any time.
SealedFiraUnlocker Contract:
  • This contract allows users to deposit a specified staking token in exchange for a payout token after a lock duration has passed.
  • When a user deposits staking tokens, the deposited amount will be locked in the contract for a specified lock duration.
  • Additional deposits will not affect the unlock time of previous deposits.
  • Once a deposit's lock duration has passed, a user can redeem the original deposit amount in the form of a payout token.
  • The originally deposited staking tokens will remain in the contract.
  • An emergency withdraw function exists, allowing users to withdraw all of their staked tokens at any time.
  • If the staked token address is set to 0, users will not be able to redeem the payout token.
  • The owner can update the lock duration at any time.
  • The owner can withdraw any token from the contract at any time.
  • The owner can update the staking token or payout token at any time.
  • This contract can be upgraded at any time.
  • ReentrancyGuard is utilized to prevent reentrancy attacks in applicable functions.
StakingPool Contract:
  • This contract allows users to deposit a specified staking token in order to earn various rewards over time.
  • Rewards for each token in the reward token list are accrued over time at a rate of each token's specified "reward speed".
  • Rewards can be in the form of the blockchain's native token and other tokens.
  • Users' pending rewards are updated at each deposit, withdrawal, and claim; however, users must call the claimRewards() function in order to receive their accrued rewards.
  • When withdrawing staking tokens, users must pay a specified withdraw fee based on the time since their last deposit.
  • The withdraw fee is sent to a specified "withdraw fee receiver" address.
  • Contracts are not permitted to deposit, withdraw, or claim rewards unless the contract has been added to a contract Whitelist.
  • The owner can update the withdraw fees, time intervals for fee calculations, and withdraw fee receiver address at any time.
  • The owner can update the reward token list at any time.
  • The FarmController contract can update the reward speed for any reward token at any time.
  • The owner can update the FarmController contract at any time.
  • The owner can update the staking token at any time. If the staking token is changed after a user has deposited, they will be unable to withdraw the same tokens that they deposited.
  • The owner can withdraw any tokens from the contract at any time, including the staking token and the blockchain's native token.
  • The team should not use the staking token as a reward token as rewards may be funded with staked funds if the contract is not adequately supplied rewards.
  • This contract can be upgraded at any time.
  • ReentrancyGuard is utilized to prevent reentrancy attacks in applicable functions.
FarmController Contract:
  • This contract controls and facilitates interactions with various StakingPool contracts.
  • Users can stake funds into various pools, each of which has an associated StakingPool contract.
  • Depositing or withdrawing from a pool simply deposits or withdraws from the pool's StakingPool contract.
  • Users may provide a list of pool IDs to harvest any available rewards from each specified pool.
  • The reward speeds of a pool's StakingPool contract is adjusted based on the number of allocation points a pool has.
  • Contracts are not permitted to deposit, withdraw, or claim rewards unless the contract has been added to a contract Whitelist.
  • The owner can update a pool's reward speed and allocation points at any time.
  • The owner can update a pool's StakingPool reward token list at any time.
  • The owner can send reward tokens from this contract to a pool's StakingPool contract at any time.
  • The owner can add a new pool or remove an existing pool at any time.
  • The owner can withdraw any of the blockchain's native token or other tokens from the contract at any time.
  • ReentrancyGuard is utilized to prevent reentrancy attacks in applicable functions.

Audit Results

Vulnerability CategoryNotesResult
Arbitrary Jump/Storage WriteN/APASS
Centralization of Control
  • The owner has the permissions described above.
  • The fee setter address can update swap fees at any time.
  • Authorized users can mint any amount of $sFIRA and $FIRA tokens at any time.
  • The owner of the StakingPool and SealedFiraUnlocker contracts can update their staking tokens at any time.
  • The owner of the StakingPool contract can update withdraw fees to any amount at any time.
  • The owner of the StakingPool, FarmController, and SealedFiraUnlocker contracts can withdraw any funds from the contract at any time.
WARNING
Compiler IssuesN/APASS
Delegate Call to Untrusted ContractN/APASS
Dependence on Predictable VariablesN/APASS
Ether/Token TheftN/APASS
Flash LoansN/APASS
Front RunningN/APASS
Improper EventsN/APASS
Improper Authorization SchemeN/APASS
Integer Over/UnderflowN/APASS
Logical IssuesLock times may be inadvertently extended as mentioned in Finding #1.WARNING
Oracle IssuesN/APASS
Outdated Compiler VersionN/APASS
Race ConditionsN/APASS
ReentrancyN/APASS
Signature IssuesN/APASS
Unbounded LoopsN/APASS
Unused CodeN/APASS
Overall Contract Safety PASS

Contract Source Summary and Visualizations

Name

Address/Source Code

Visualized
(Hover-Zoom Recommended)

UniswapV2Factory

N/A

Inheritance Chart.  Function Graph.

UniswapV2Router02

N/A

Inheritance Chart.  Function Graph.

SealedFira

N/A

Inheritance Chart.  Function Graph.

Fira

N/A

Inheritance Chart.  Function Graph.

FiraCirculatingSupply

N/A

Inheritance Chart.  Function Graph.

SealedFiraUnlocker

N/A

Inheritance Chart.  Function Graph.

StakingPool

N/A

Inheritance Chart.  Function Graph.

FarmController

N/A

Inheritance Chart.  Function Graph.

About SourceHat

SourceHat has quickly grown to have one of the most experienced and well-equipped smart contract auditing teams in the industry. Our team has conducted 1800+ solidity smart contract audits covering all major project types and protocols, securing a total of over $50 billion U.S. dollars in on-chain value!
Our firm is well-reputed in the community and is trusted as a top smart contract auditing company for the review of solidity code, no matter how complex. Our team of experienced solidity smart contract auditors performs audits for tokens, NFTs, crowdsales, marketplaces, gambling games, financial protocols, and more!

Contact us today to get a free quote for a smart contract audit of your project!

What is a SourceHat Audit?

Typically, a smart contract audit is a comprehensive review process designed to discover logical errors, security vulnerabilities, and optimization opportunities within code. A SourceHat Audit takes this a step further by verifying economic logic to ensure the stability of smart contracts and highlighting privileged functionality to create a report that is easy to understand for developers and community members alike.

How Do I Interpret the Findings?

Each of our Findings will be labeled with a Severity level. We always recommend the team resolve High, Medium, and Low severity findings prior to deploying the code to the mainnet. Here is a breakdown on what each Severity level means for the project:

  • High severity indicates that the issue puts a large number of users' funds at risk and has a high probability of exploitation, or the smart contract contains serious logical issues which can prevent the code from operating as intended.
  • Medium severity issues are those which place at least some users' funds at risk and has a medium to high probability of exploitation.
  • Low severity issues have a relatively minor risk association; these issues have a low probability of occurring or may have a minimal impact.
  • Informational issues pose no immediate risk, but inform the project team of opportunities for gas optimizations and following smart contract security best practices.