Perpetual Yield

Smart Contract Audit Report

Audit Summary

Yieldification is releasing a new options platform with profits paid in YDF tokens.

For this audit, we reviewed the following contracts on the Ethereum Mainnet:

We previously reviewed the project team's token and staking contracts here.

Audit Findings

Medium findings were identified and the team should resolve these issues. In addition, centralized aspects are present.
Date: November 17th, 2022.

Finding #1 - PerpetualFutures - Medium

Description: The team has no ability to withdraw the ETH fees collected.
Risk/Impact: Any ETH fees collected will be stuck in the contract.
Recommendation: The team should add an owner restricted function to withdraw ETH from the contract.
Resolution: The team has not yet addressed this issue.

Finding #2 - PerpetualFutures - Low

Description: The contract does not track the total amount of fees collected.
Risk/Impact: The team must rely on events emitted or iterating over all positions to accurately determine the total fees collected in the contract.
Recommendation: The team should track the total fees collected to allow them to withdraw fees more easily. The total fees should be reset to 0 when withdrawn.
Resolution: The team has not yet addressed this issue.

Finding #3 - Bridge - Informational

Description: The contract contains a sourceConfirmations value and setSourceConfirmations() function that are not used within the contract.
Recommendation: The team should consider removing this value and function to save on contract size and deployment costs.

Finding #4 - PerpetualFutures - Informational

Description: The contract maintains a large structure in memory for each position that is opened. These structures are never deleted.
Recommendation: The team should consider deleting positions after they are closed to prevent excess memory usage.

Contracts Overview

  • As the contracts are implemented with Solidity v0.8.16, they are safe from any possible overflows/underflows.
pfYDF Contract:
  • This contract defines the pfYDF ERC-721 NFTs.
  • The contract allows conforms to the ERC-2981 Royalty standard for distributing royalties in NFT marketplaces.
  • The PerpetualFutures contract may mint any address an NFT at any time.
  • The PerpetualFutures contract may burn any NFT at any time.
  • The owner may set the Royalty address and royalty basis points at any time.
  • The owner may set the base URI at any time.
  • The owner may set the PerpetualFutures address at any time.
PerpetualFutures Contract:
  • This contract allows users to take long and short positions against various Indexes using ETH or any supported collateral token.
  • When trading is enabled, any address may open a position against a specified Index by providing collateral.
  • The contract properly accounts for fee-on-transfer tokens where applicable.
  • Indexes may have restrictions preventing users from opening a position on certain days of the week or during specific hours of a given day.
  • Users may specify an amount of leverage.
  • The total size of the position will be multiplied by the leverage chosen.
  • A "position opening" fee will be taken from the provided collateral.
  • Leveraged positions will be charged a larger fee proportional to the amount of leverage.
  • A discount may be applied to the opening fee if the FeeReducer address has been set by the team.
  • The current Index price at the time of opening is determined using PriceFeeds. The PriceFeeds are intended to be Chainlink Data Feeds.
  • Each PriceFeed associated with the Index will fetch the current price of the asset it is tracking.
  • If there is more than 1 PriceFeed, the cumulative price will be determined based on the "weight" of each PriceFeed where a higher weight will have more impact on the price.
  • The position will not be opened if the Index's current price is outside of the allowed slippage specified by the user.
  • The position will also not be opened if the difference between the total amount of open short and long positions for the collateral token would exceed the maximum "open difference" value.
  • Users will be minted a pfYDF NFT representing ownership of their position on the platform.
  • The user may additionally create a "trigger order" when opening a position.
  • A trigger order will close the position if the index hits a specified target price during "upkeep".
  • Users may close one of their open positions at any time.
  • The closing user will be returned any remaining collateral after fees and losses.
  • The position will be put into an "unsettled position" if it resulted in an overall profit and the collateral token is not YDF.
  • Positions that are in the profit and using YDF as collateral will receive the collateral and profit when closing.
  • Any profit will be forfeited if the starting price is not the "minimum price difference for profit" from the opening price or the "minimum open time for profit" has not passed from when the position was opened.
  • A "position closing" fee will be taken based on the total size of the position and a "position duration" fee will be taken based on the amount of time the position was open.
  • A discount may be applied to the closing fees if the FeeReducer address has been set by the team.
  • The pfYDF NFT representing the position will be burned.
  • The Settler address may settle an unsettled position at any time.
  • The position owner will be transferred the profit from the position in the form of YDF tokens.
  • Sufficient tokens must be supplied to the contract to pay out profits.
  • Users may add and remove a trigger order from a position at any time. Each user may only have up to the "max trigger orders" number of trigger orders at once.
  • Users may update the target price for a trigger order at any time. The target price must stay greater than the current price if the original target price was greater than the current price. The target price must stay lower than the current price if the original target price was lower than the current price.
  • Any address may check if "upkeep" is needed. The contract will iterate over all open positions and check if they are liquidable if or one of their trigger prices have been reached.
  • A position is liquidable if the current price has passed the liquidation threshold.
  • The liquidation threshold is determined from the price of the Index when the position was opened and the position's leverage.
  • Any address may perform upkeep at any time. The contract will iterate over all open positions and liquidate or close all applicable positions. Only the "maxLiquidationsPerUpkeep" positions will be closed at once.
  • The upkeep functionality is intended to be run periodically by Chainlink Keepers.
  • The owner may add and remove a token as a valid collateral token at any time.
  • The owner may update the main collateral token address at any time. This is intended to be the YDF token.
  • The owner may set the max leverage, up to 250, at any time.
  • The owner may set the max number of trigger orders for each user to any value at any time.
  • The owner may set the minimum duration for a position to collect profit, up to 1 day, at any time.
  • The owner may set the minimum price change for a position to collect profit, up to a 10% change, at any time.
  • The owner may set the close and open position fees, up to 10%, at any time.
  • The owner may update the Settler and FeeReducer addresses at any time.
  • The owner may set the maximum allowed difference between long and short positions to any value at any time.
  • The owner may set the max liquidations per upkeep to any non-zero value at any time.
  • The owner may add and remove an Index at any time.
  • The owner may update the weight for each PriceFeed in an Index at any time.
  • The owner may set the hours and days an Index may have a position opened at any time.
  • The owner may enable and disable trading at any time.
  • The owner may withdraw any token from the contract at any time.
slYDFZapper Contract:
  • This contract serves as a wrapper for staking YDF tokens and ETH in the slYDF contract.
  • Users may stake using just ETH, just YDF, or both.
  • When staking with only ETH, half of the supplied ETH will be swapped for YDF tokens.
  • The remaining ETH will be paired with the received YDF tokens and staked in the slYDF contract.
  • The user will be transferred all received slYDF tokens.
  • When staking with only YDF, half of the supplied YDF will be swapped for ETH.
  • The remaining YDF will be paired with the received ETH and staked in the slYDF contract.
  • The user will be transferred all received slYDF tokens.
  • When staking with both YDF and ETH, the supplied tokens will be paired and staked in the slYDF contract.
  • The user will be transferred all received slYDF tokens.
  • All staking functions will return any excess ETH and YDF tokens remaining after staking.
  • The contract properly accounts for fee-on-transfer tokens where applicable.
Bridge Contract:
  • This contract uses Relay addresses to transfer tokens between users across chains.
  • The contract requires the use of off-chain logic. This is outside the scope of this audit so we cannot give an assessment in regard to security.
  • Any user may initiate a transaction when the contract is active.
  • Users must pay the "bridge cost" when initiating a transaction.
  • The specified amount of tokens will be transferred from the user and stored in the contract.
  • Any Relay address may "initiate a delivery" when the contract is active. This will allocate a specified amount of tokens for an address.
  • A Relay address may "deliver" an initiated delivery when the contract is active. The delivering Relay address must be different from the Relay address that initiated the delivery.
  • A delivery will transfer the tokens allocated in the initiation to the specified address.
  • Any Relay address may mark a "source" as complete. This will remove the data associated with a transaction that has been initiated but is incomplete and mark the transaction as completed.
  • The contract does not properly accounts for fee-on-transfer tokens, though it is intended to be used with YDF tokens which would not take fees on a peer-to-peer transfer. If the team intends to use a fee-on-transfer token, the contract must be restructured or properly excluded from fees.
  • The owner may toggle whether the contract is active at any time.
  • The owner may set the bridge cost to any value at any time.
  • The owner may add and remove a Relay address at any time.
  • The owner may set the source confirmations to any value at any time.
  • The owner may withdraw all tokens and ETH from the contract at any time.

Audit Results

Vulnerability Category Notes Result
Arbitrary Jump/Storage Write N/A PASS
Centralization of Control
  • The PerpetualFutures owner may disable trading at any time.
  • The PerpetualFutures owner may withdraw all tokens from the contract.
  • The Bridge owner may withdraw all tokens from contract.
  • The Bridge owner may set the bridge cost to any amount.
WARNING
Compiler Issues N/A PASS
Delegate Call to Untrusted Contract N/A PASS
Dependence on Predictable Variables N/A PASS
Ether/Token Theft N/A PASS
Flash Loans N/A PASS
Front Running N/A PASS
Improper Events N/A PASS
Improper Authorization Scheme N/A PASS
Integer Over/Underflow N/A PASS
Logical Issues The team has no ability to withdraw ETH fees collected. WARNING
Oracle Issues N/A PASS
Outdated Compiler Version N/A PASS
Race Conditions N/A PASS
Reentrancy N/A PASS
Signature Issues N/A PASS
Sybil Attack N/A PASS
Unbounded Loops N/A PASS
Unused Code N/A PASS
Overall Contract Safety   WARNING

pfYDF Contract

Smart Contract Audit - Inheritance

Smart Contract Audit - Graph


 ($) = payable function
 # = non-constant function
 
 Int = Internal
 Ext = External
 Pub = Public
 
 +  AutomationBase 
    - [Int] preventExecution

 + [Int] AutomationCompatibleInterface 
    - [Ext] checkUpkeep #
    - [Ext] performUpkeep #

 +  AutomationCompatible (AutomationBase, AutomationCompatibleInterface)

 +  Context 
    - [Int] _msgSender
    - [Int] _msgData

 +  Ownable (Context)
    - [Pub] Constructor #
    - [Pub] owner
    - [Int] _checkOwner
    - [Pub] renounceOwnership #
       - modifiers: onlyOwner
    - [Pub] transferOwnership #
       - modifiers: onlyOwner
    - [Int] _transferOwnership #

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

 + [Int] IERC165 
    - [Ext] supportsInterface

 + [Int] IERC721 (IERC165)
    - [Ext] balanceOf
    - [Ext] ownerOf
    - [Ext] safeTransferFrom #
    - [Ext] safeTransferFrom #
    - [Ext] transferFrom #
    - [Ext] approve #
    - [Ext] setApprovalForAll #
    - [Ext] getApproved
    - [Ext] isApprovedForAll

 + [Int] IERC721Receiver 
    - [Ext] onERC721Received #

 + [Int] IERC721Metadata (IERC721)
    - [Ext] name
    - [Ext] symbol
    - [Ext] tokenURI

 + [Lib] Address 
    - [Int] isContract
    - [Int] sendValue #
    - [Int] functionCall #
    - [Int] functionCall #
    - [Int] functionCallWithValue #
    - [Int] functionCallWithValue #
    - [Int] functionStaticCall
    - [Int] functionStaticCall
    - [Int] functionDelegateCall #
    - [Int] functionDelegateCall #
    - [Int] verifyCallResultFromTarget
    - [Int] verifyCallResult
    - [Prv] _revert

 + [Lib] Math 
    - [Int] max
    - [Int] min
    - [Int] average
    - [Int] ceilDiv
    - [Int] mulDiv
    - [Int] mulDiv
    - [Int] sqrt
    - [Int] sqrt
    - [Int] log2
    - [Int] log2
    - [Int] log10
    - [Int] log10
    - [Int] log256
    - [Int] log256

 + [Lib] Strings 
    - [Int] toString
    - [Int] toHexString
    - [Int] toHexString
    - [Int] toHexString

 +  ERC165 (IERC165)
    - [Pub] supportsInterface

 +  ERC721 (Context, ERC165, IERC721, IERC721Metadata)
    - [Pub] Constructor #
    - [Pub] supportsInterface
    - [Pub] balanceOf
    - [Pub] ownerOf
    - [Pub] name
    - [Pub] symbol
    - [Pub] tokenURI
    - [Int] _baseURI
    - [Pub] approve #
    - [Pub] getApproved
    - [Pub] setApprovalForAll #
    - [Pub] isApprovedForAll
    - [Pub] transferFrom #
    - [Pub] safeTransferFrom #
    - [Pub] safeTransferFrom #
    - [Int] _safeTransfer #
    - [Int] _ownerOf
    - [Int] _exists
    - [Int] _isApprovedOrOwner
    - [Int] _safeMint #
    - [Int] _safeMint #
    - [Int] _mint #
    - [Int] _burn #
    - [Int] _transfer #
    - [Int] _approve #
    - [Int] _setApprovalForAll #
    - [Int] _requireMinted
    - [Prv] _checkOnERC721Received #
    - [Int] _beforeTokenTransfer #
    - [Int] _afterTokenTransfer #

 + [Int] IERC721Enumerable (IERC721)
    - [Ext] totalSupply
    - [Ext] tokenOfOwnerByIndex
    - [Ext] tokenByIndex

 +  ERC721Enumerable (ERC721, IERC721Enumerable)
    - [Pub] supportsInterface
    - [Pub] tokenOfOwnerByIndex
    - [Pub] totalSupply
    - [Pub] tokenByIndex
    - [Int] _beforeTokenTransfer #
    - [Prv] _addTokenToOwnerEnumeration #
    - [Prv] _addTokenToAllTokensEnumeration #
    - [Prv] _removeTokenFromOwnerEnumeration #
    - [Prv] _removeTokenFromAllTokensEnumeration #

 + [Lib] Counters 
    - [Int] current
    - [Int] increment #
    - [Int] decrement #
    - [Int] reset #

 + [Int] AggregatorInterface 
    - [Ext] latestAnswer
    - [Ext] latestTimestamp
    - [Ext] latestRound
    - [Ext] getAnswer
    - [Ext] getTimestamp

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

 + [Int] AggregatorV2V3Interface (AggregatorInterface, AggregatorV3Interface)

 + [Int] PriceFeedProxy (AggregatorV2V3Interface)
    - [Ext] aggregator
    - [Ext] phaseId

 +  IndexHandler 
    - [Pub] getIndexPriceFromIndex
    - [Pub] getIndexPriceFromFeeds
    - [Pub] getLatestProxyInfo

 +  pfYDF (ERC721Enumerable, Ownable)
    - [Pub] Constructor #
       - modifiers: ERC721
    - [Ext] mint #
       - modifiers: onlyPerps
    - [Ext] burn #
       - modifiers: onlyPerps
    - [Ext] royaltyInfo
    - [Pub] tokenURI
    - [Pub] contractURI
    - [Pub] supportsInterface
    - [Ext] getLastMintedTokenId
    - [Ext] doesTokenExist
    - [Ext] setRoyaltyAddress #
       - modifiers: onlyOwner
    - [Ext] setRoyaltyBasisPoints #
       - modifiers: onlyOwner
    - [Ext] setBaseURI #
       - modifiers: onlyOwner
    - [Ext] setPerpetualFutures #
       - modifiers: onlyOwner
    - [Ext] getAllUserOwned
    - [Int] _baseURI
    - [Int] _beforeTokenTransfer #
    - [Int] _afterTokenTransfer #

PerpetualFutures Contract

Smart Contract Audit - Inheritance

Smart Contract Audit - Graph


 ($) = payable function
 # = non-constant function
 
 Int = Internal
 Ext = External
 Pub = Public
 
 +  AutomationBase 
    - [Int] preventExecution

 + [Int] AutomationCompatibleInterface 
    - [Ext] checkUpkeep #
    - [Ext] performUpkeep #

 +  AutomationCompatible (AutomationBase, AutomationCompatibleInterface)

 +  Context 
    - [Int] _msgSender
    - [Int] _msgData

 +  Ownable (Context)
    - [Pub] Constructor #
    - [Pub] owner
    - [Int] _checkOwner
    - [Pub] renounceOwnership #
       - modifiers: onlyOwner
    - [Pub] transferOwnership #
       - modifiers: onlyOwner
    - [Int] _transferOwnership #

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

 + [Int] IERC20Metadata (IERC20)
    - [Ext] name
    - [Ext] symbol
    - [Ext] decimals

 +  ERC20 (Context, IERC20, IERC20Metadata)
    - [Pub] Constructor #
    - [Pub] name
    - [Pub] symbol
    - [Pub] decimals
    - [Pub] totalSupply
    - [Pub] balanceOf
    - [Pub] transfer #
    - [Pub] allowance
    - [Pub] approve #
    - [Pub] transferFrom #
    - [Pub] increaseAllowance #
    - [Pub] decreaseAllowance #
    - [Int] _transfer #
    - [Int] _mint #
    - [Int] _burn #
    - [Int] _approve #
    - [Int] _spendAllowance #
    - [Int] _beforeTokenTransfer #
    - [Int] _afterTokenTransfer #

 + [Int] IERC20Permit 
    - [Ext] permit #
    - [Ext] nonces
    - [Ext] DOMAIN_SEPARATOR

 + [Lib] Address 
    - [Int] isContract
    - [Int] sendValue #
    - [Int] functionCall #
    - [Int] functionCall #
    - [Int] functionCallWithValue #
    - [Int] functionCallWithValue #
    - [Int] functionStaticCall
    - [Int] functionStaticCall
    - [Int] functionDelegateCall #
    - [Int] functionDelegateCall #
    - [Int] verifyCallResultFromTarget
    - [Int] verifyCallResult
    - [Prv] _revert

 + [Lib] SafeERC20 
    - [Int] safeTransfer #
    - [Int] safeTransferFrom #
    - [Int] safeApprove #
    - [Int] safeIncreaseAllowance #
    - [Int] safeDecreaseAllowance #
    - [Int] safePermit #
    - [Prv] _callOptionalReturn #

 + [Int] IFeeReducer 
    - [Ext] percentDiscount

 + [Int] IBokkyPooBahsDateTime 
    - [Ext] getDayOfWeek
    - [Ext] getHour

 + [Int] AggregatorInterface 
    - [Ext] latestAnswer
    - [Ext] latestTimestamp
    - [Ext] latestRound
    - [Ext] getAnswer
    - [Ext] getTimestamp

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

 + [Int] AggregatorV2V3Interface (AggregatorInterface, AggregatorV3Interface)

 + [Int] PriceFeedProxy (AggregatorV2V3Interface)
    - [Ext] aggregator
    - [Ext] phaseId

 +  IndexHandler 
    - [Pub] getIndexPriceFromIndex
    - [Pub] getIndexPriceFromFeeds
    - [Pub] getLatestProxyInfo

 + [Int] IERC165 
    - [Ext] supportsInterface

 + [Int] IERC721 (IERC165)
    - [Ext] balanceOf
    - [Ext] ownerOf
    - [Ext] safeTransferFrom #
    - [Ext] safeTransferFrom #
    - [Ext] transferFrom #
    - [Ext] approve #
    - [Ext] setApprovalForAll #
    - [Ext] getApproved
    - [Ext] isApprovedForAll

 + [Int] IERC721Receiver 
    - [Ext] onERC721Received #

 + [Int] IERC721Metadata (IERC721)
    - [Ext] name
    - [Ext] symbol
    - [Ext] tokenURI

 + [Lib] Math 
    - [Int] max
    - [Int] min
    - [Int] average
    - [Int] ceilDiv
    - [Int] mulDiv
    - [Int] mulDiv
    - [Int] sqrt
    - [Int] sqrt
    - [Int] log2
    - [Int] log2
    - [Int] log10
    - [Int] log10
    - [Int] log256
    - [Int] log256

 + [Lib] Strings 
    - [Int] toString
    - [Int] toHexString
    - [Int] toHexString
    - [Int] toHexString

 +  ERC165 (IERC165)
    - [Pub] supportsInterface

 +  ERC721 (Context, ERC165, IERC721, IERC721Metadata)
    - [Pub] Constructor #
    - [Pub] supportsInterface
    - [Pub] balanceOf
    - [Pub] ownerOf
    - [Pub] name
    - [Pub] symbol
    - [Pub] tokenURI
    - [Int] _baseURI
    - [Pub] approve #
    - [Pub] getApproved
    - [Pub] setApprovalForAll #
    - [Pub] isApprovedForAll
    - [Pub] transferFrom #
    - [Pub] safeTransferFrom #
    - [Pub] safeTransferFrom #
    - [Int] _safeTransfer #
    - [Int] _ownerOf
    - [Int] _exists
    - [Int] _isApprovedOrOwner
    - [Int] _safeMint #
    - [Int] _safeMint #
    - [Int] _mint #
    - [Int] _burn #
    - [Int] _transfer #
    - [Int] _approve #
    - [Int] _setApprovalForAll #
    - [Int] _requireMinted
    - [Prv] _checkOnERC721Received #
    - [Int] _beforeTokenTransfer #
    - [Int] _afterTokenTransfer #

 + [Int] IERC721Enumerable (IERC721)
    - [Ext] totalSupply
    - [Ext] tokenOfOwnerByIndex
    - [Ext] tokenByIndex

 +  ERC721Enumerable (ERC721, IERC721Enumerable)
    - [Pub] supportsInterface
    - [Pub] tokenOfOwnerByIndex
    - [Pub] totalSupply
    - [Pub] tokenByIndex
    - [Int] _beforeTokenTransfer #
    - [Prv] _addTokenToOwnerEnumeration #
    - [Prv] _addTokenToAllTokensEnumeration #
    - [Prv] _removeTokenFromOwnerEnumeration #
    - [Prv] _removeTokenFromAllTokensEnumeration #

 + [Lib] Counters 
    - [Int] current
    - [Int] increment #
    - [Int] decrement #
    - [Int] reset #

 +  pfYDF (ERC721Enumerable, Ownable)
    - [Pub] Constructor #
       - modifiers: ERC721
    - [Ext] mint #
       - modifiers: onlyPerps
    - [Ext] burn #
       - modifiers: onlyPerps
    - [Ext] royaltyInfo
    - [Pub] tokenURI
    - [Pub] contractURI
    - [Pub] supportsInterface
    - [Ext] getLastMintedTokenId
    - [Ext] doesTokenExist
    - [Ext] setRoyaltyAddress #
       - modifiers: onlyOwner
    - [Ext] setRoyaltyBasisPoints #
       - modifiers: onlyOwner
    - [Ext] setBaseURI #
       - modifiers: onlyOwner
    - [Ext] setPerpetualFutures #
       - modifiers: onlyOwner
    - [Ext] getAllUserOwned
    - [Int] _baseURI
    - [Int] _beforeTokenTransfer #
    - [Int] _afterTokenTransfer #

 +  PerpetualFutures (IndexHandler, KeeperCompatibleInterface, Ownable)
    - [Pub] Constructor #
    - [Ext] getFeeReducer
    - [Ext] getPerpsNFT
    - [Ext] getAllIndexes
    - [Ext] getAllValidCollateralTokens
    - [Ext] getAllUnsettledPositions
    - [Ext] getAllPositionTriggerOrders
    - [Ext] openPosition ($)
    - [Int] _processOpenCollateral #
    - [Int] _validateOpenPriceSlip
    - [Int] _createNewPosition #
    - [Int] _canOpenAgainstIndex
    - [Int] _doTimeBoundsPass
    - [Ext] closePosition #
    - [Int] _closePosition #
    - [Ext] settleUnsettledPosition #
       - modifiers: onlySettler
    - [Pub] getIndexAndPLInfo
    - [Pub] getLiquidationPriceChange
    - [Pub] getPositionIndexPrice
    - [Pub] getPositionCloseFees
    - [Ext] getPositionIndexProxies
    - [Ext] addTriggerOrder #
       - modifiers: onlyPositionOwner
    - [Ext] updateTriggerOrder #
       - modifiers: onlyPositionOwner
    - [Ext] removeTriggerOrder #
       - modifiers: onlyPositionOwner
    - [Int] _addTriggerOrder #
    - [Int] _updateTriggerOrder #
    - [Int] _removeTriggerOrder #
    - [Ext] setValidCollateralToken #
       - modifiers: onlyOwner
    - [Ext] setMainCollateralToken #
       - modifiers: onlyOwner
    - [Ext] setMaxLeverage #
       - modifiers: onlyOwner
    - [Ext] setMaxTriggerOrders #
       - modifiers: onlyOwner
    - [Ext] setMinOpenTimeForProfit #
       - modifiers: onlyOwner
    - [Ext] setMinPriceDiffForProfit #
       - modifiers: onlyOwner
    - [Ext] setOpenFeePositionSize #
       - modifiers: onlyOwner
    - [Ext] setCloseFeePositionSize #
       - modifiers: onlyOwner
    - [Ext] setCloseFeePositionPerDurationUnit #
       - modifiers: onlyOwner
    - [Ext] setClosePositionFeePerDuration #
       - modifiers: onlyOwner
    - [Ext] setSettler #
       - modifiers: onlyOwner
    - [Ext] setMaxCollateralOpenDiff #
       - modifiers: onlyOwner
    - [Ext] setMaxLiquidationsPerUpkeep #
       - modifiers: onlyOwner
    - [Ext] addIndex #
       - modifiers: onlyOwner
    - [Ext] removeIndex #
       - modifiers: onlyOwner
    - [Ext] refreshIndexFeedWeights #
       - modifiers: onlyOwner
    - [Ext] updateIndexOpenTimeBounds #
       - modifiers: onlyOwner
    - [Ext] setTradingEnabled #
       - modifiers: onlyOwner
    - [Ext] setFeeReducer #
       - modifiers: onlyOwner
    - [Ext] processFees #
       - modifiers: onlyOwner
    - [Ext] withdrawERC20 #
       - modifiers: onlyOwner
    - [Ext] checkUpkeep
    - [Ext] performUpkeep #
    - [Pub] checkAndLiquidatePosition #
    - [Pub] getFeeDiscount
    - [Int] _getPositionOpenFee
    - [Int] _addOpenPosition #
    - [Int] _removeOpenPosition #
    - [Int] _checkAndSettlePosition #
    - [Int] _getAndClosePositionPLInfo #
    - [Int] _closeIndividualFeeds #
    - [Int] _validateAndUpdateOpenAmounts #
    - [Int] _updateCloseAmounts #
    - [Pub] shouldPositionLiquidate
    - [Pub] shouldPositionCloseFromTrigger

slYDFZapper Contract

Smart Contract Audit - Inheritance

Smart Contract Audit - Graph


 ($) = payable function
 # = non-constant function
 
 Int = Internal
 Ext = External
 Pub = Public
 
 + [Int] IERC20 
    - [Ext] totalSupply
    - [Ext] balanceOf
    - [Ext] transfer #
    - [Ext] allowance
    - [Ext] approve #
    - [Ext] transferFrom #

 + [Int] IERC721Receiver 
    - [Ext] onERC721Received #

 + [Int] IUniswapV2Pair 
    - [Ext] name
    - [Ext] symbol
    - [Ext] decimals
    - [Ext] totalSupply
    - [Ext] balanceOf
    - [Ext] allowance
    - [Ext] approve #
    - [Ext] transfer #
    - [Ext] transferFrom #
    - [Ext] DOMAIN_SEPARATOR
    - [Ext] PERMIT_TYPEHASH
    - [Ext] nonces
    - [Ext] permit #
    - [Ext] MINIMUM_LIQUIDITY
    - [Ext] factory
    - [Ext] token0
    - [Ext] token1
    - [Ext] getReserves
    - [Ext] price0CumulativeLast
    - [Ext] price1CumulativeLast
    - [Ext] kLast
    - [Ext] mint #
    - [Ext] burn #
    - [Ext] swap #
    - [Ext] skim #
    - [Ext] sync #
    - [Ext] initialize #

 + [Int] IUniswapV2Router01 
    - [Ext] factory
    - [Ext] WETH
    - [Ext] addLiquidity #
    - [Ext] addLiquidityETH ($)
    - [Ext] removeLiquidity #
    - [Ext] removeLiquidityETH #
    - [Ext] removeLiquidityWithPermit #
    - [Ext] removeLiquidityETHWithPermit #
    - [Ext] swapExactTokensForTokens #
    - [Ext] swapTokensForExactTokens #
    - [Ext] swapExactETHForTokens ($)
    - [Ext] swapTokensForExactETH #
    - [Ext] swapExactTokensForETH #
    - [Ext] swapETHForExactTokens ($)
    - [Ext] quote
    - [Ext] getAmountOut
    - [Ext] getAmountIn
    - [Ext] getAmountsOut
    - [Ext] getAmountsIn

 + [Int] IUniswapV2Router02 (IUniswapV2Router01)
    - [Ext] removeLiquidityETHSupportingFeeOnTransferTokens #
    - [Ext] removeLiquidityETHWithPermitSupportingFeeOnTransferTokens #
    - [Ext] swapExactTokensForTokensSupportingFeeOnTransferTokens #
    - [Ext] swapExactETHForTokensSupportingFeeOnTransferTokens ($)
    - [Ext] swapExactTokensForETHSupportingFeeOnTransferTokens #

 + [Int] IERC165 
    - [Ext] supportsInterface

 + [Int] IERC721 (IERC165)
    - [Ext] balanceOf
    - [Ext] ownerOf
    - [Ext] safeTransferFrom #
    - [Ext] safeTransferFrom #
    - [Ext] transferFrom #
    - [Ext] approve #
    - [Ext] setApprovalForAll #
    - [Ext] getApproved
    - [Ext] isApprovedForAll

 + [Int] IslYDF (IERC721)
    - [Ext] getAllUserOwned
    - [Ext] zapAndStakeETHAndYDF ($)

 +  slYDFZapper (IERC721Receiver)
    - [Pub] Constructor #
    - [Ext] onERC721Received
    - [Ext] zapAndStakeETHOnly ($)
    - [Ext] zapAndStakeETHAndYDF ($)
    - [Ext] zapAndStakeYDFOnly #
    - [Int] _addAndStakeLp #
    - [Int] _returnExcessETH #
    - [Int] _returnExcessYDF #
    - [Ext] Receive Ether ($)

Bridge Contract

Smart Contract Audit - Inheritance

Smart Contract Audit - Graph


 ($) = payable function
 # = non-constant function
 
 Int = Internal
 Ext = External
 Pub = Public
 
 +  Context 
    - [Int] _msgSender
    - [Int] _msgData

 +  Ownable (Context)
    - [Pub] Constructor #
    - [Pub] owner
    - [Int] _checkOwner
    - [Pub] renounceOwnership #
       - modifiers: onlyOwner
    - [Pub] transferOwnership #
       - modifiers: onlyOwner
    - [Int] _transferOwnership #

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

 +  Bridge (Ownable)
    - [Ext] getBridgeToken
    - [Ext] getIncompleteSources
    - [Ext] getIncompleteReceivers
    - [Ext] setBridgeToken #
       - modifiers: onlyOwner
    - [Ext] setIsActive #
       - modifiers: onlyOwner
    - [Ext] setBridgeCost #
       - modifiers: onlyOwner
    - [Ext] setRelay #
       - modifiers: onlyOwner
    - [Ext] create ($)
    - [Ext] setSourceComplete #
       - modifiers: onlyRelay
    - [Ext] initDeliver #
       - modifiers: onlyRelay
    - [Ext] deliver #
       - modifiers: onlyRelay
    - [Ext] setSourceConfirmations #
       - modifiers: onlyOwner
    - [Ext] withdrawERC20 #
       - modifiers: onlyOwner
    - [Ext] withdrawETH #
       - modifiers: onlyOwner

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 Solidity Audit?

Typically, a smart contract audit is a comprehensive review process designed to discover logical errors, security vulnerabilities, and optimization opportunities within code. A Solidity 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.