Buffer Finance - Smart Contract Audit Report

Summary

Buffer.finance Buffer Finance is building a staking platform and an options platform.

For this audit we reviewed the project's BufferBNBPool, BufferBNBPredictions, BufferStaking, and BufferStakingBNB contracts at commit efd2570b1cb46b64fb841938e1137c5fcd8722b2 on the team's GitHub repository.

Notes on the Contracts:

BufferBNBPool
  • In this contract, users stake BNB in exchange for Buffer BNB LP Tokens. it is also used by Buffer Finance's options contracts.
  • Any time a user deposits funds, the entirety of their staked funds will be locked for a period of time before they can withdraw their BNB. The lockup period is initially set to 2 weeks, however addresses with the OPTION_ISSUER_ROLE can change this to any value up to 60 days.
  • Note that if a user receives LP tokens from a user whose funds are locked, the receiver's lock duration will be set equal to the sender's. Users can opt to accept/not accept locked fund transfers at any time.
  • The owner is able to grant or revoke the OPTION_ISSUER_ROLE from any address at any time.
BufferStakingBNB
  • Users can deposit buffer tokens and will receive Buffer BNB Staking tokens in a 1:1 exchange; the owner defines the buffer token address upon deployment.
  • Users must wait at least 1 day before exchanging Buffer BNB Staking tokens back to buffer tokens.
  • Users are entitled to a share of profits from the pool based on the number of Buffer BNB Staking tokens they have; at this time the contract has no way to accumulate profits on its own, so the project team must deposit ETH manually in order to fund the profit pool.
BufferBNBPredictions
  • BufferBNBPredictions allows users to create and execute options, which are ERC721 tokens with unique option ids.
  • Note that many of the functions of BufferBNBPredictions come from its base contract BaseBufferBNBOptions, which is not in the scope of this audit.
  • Users can create put or call options with a period between 1 day and 1 month. The expected change in BNB specified in the option can be set to any value up to a limit which can be changed by the owner at any time.
  • Note that the owner of the contract is given approval to use the option NFTs created by every user; all of the option NFTs can be transferred to the owner at any time and is therefore entitled to the profits upon exercising.
  • Anyone with the PREDICTION_EXERCISER role can exercise an active option that has not yet expired. Exercising an option will pay profits to the owner of the option; the NFT representing the option contract is subsequently burned.
Audit Findings Summary
  • No security issues from outside attackers were identified.
  • Ensure trust in the project team as they have substantial control in the ecosystem. The owner has the ability to transfer any user's options at any time.
  • Date: September 6th, 2021.

External Threat Results

Vulnerability CategoryNotesResult
Arbitrary Storage WriteN/APASS
Arbitrary JumpN/APASS
Delegate Call to Untrusted ContractN/APASS
Dependence on Predictable VariablesN/APASS
Deprecated OpcodesN/APASS
Ether ThiefN/APASS
ExceptionsN/APASS
External CallsN/APASS
Integer Over/UnderflowN/APASS
Multiple SendsN/APASS
SuicideN/APASS
State Change External CallsN/APASS
Unchecked RetvalN/APASS
User Supplied AssertionN/APASS
Critical Solidity CompilerN/APASS
Overall Contract Safety PASS

BufferStakingBNB Contract

Smart Contract Graph

Contract Inheritance


($) = 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] IERC20Metadata (IERC20)
    - [Ext] name
    - [Ext] symbol
    - [Ext] decimals

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

 +  ERC20 (Context, IERC20, IERC20Metadata)
    - [Pub]  #
    - [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] _beforeTokenTransfer #
    - [Int] _afterTokenTransfer #

 + [Int] ILiquidityPool 
    - [Ext] unlock #
    - [Ext] send #
    - [Ext] setLockupPeriod #
    - [Ext] totalBalance

 + [Int] IBNBLiquidityPool (ILiquidityPool)
    - [Ext] lock ($)

 + [Int] IBufferOptions 
    - [Ext] options

 + [Int] IBufferStaking 
    - [Ext] claimProfit #
    - [Ext] buy #
    - [Ext] sell #
    - [Ext] profitOf

 + [Int] IBufferStakingBNB (IBufferStaking)
    - [Ext] sendProfit ($)

 + [Int] IBufferStakingIBFR (IBufferStaking)
    - [Ext] sendProfit #

 +  BufferStaking (ERC20, IBufferStaking)
    - [Pub]  #
       - modifiers: ERC20
    - [Ext] claimProfit #
    - [Ext] buy #
    - [Ext] sell #
       - modifiers: lockupFree
    - [Ext] revertTransfersInLockUpPeriod #
    - [Ext] profitOf
    - [Int] getUnsaved
    - [Int] saveProfit #
    - [Int] _beforeTokenTransfer #
    - [Int] _transferProfit #

 +  BufferStakingBNB (BufferStaking, IBufferStakingBNB)
    - [Pub]  #
       - modifiers: BufferStaking
    - [Ext] sendProfit ($)
    - [Int] _transferProfit #

  

BufferBNBPredictions Contract

Smart Contract Graph

Contract Inheritance


($) = payable function
# = non-constant function

Int = Internal
Ext = External
Pub = Public

 + [Int] ILiquidityPool 
    - [Ext] unlock #
    - [Ext] send #
    - [Ext] setLockupPeriod #
    - [Ext] totalBalance

 + [Int] IBNBLiquidityPool (ILiquidityPool)
    - [Ext] lock ($)

 + [Int] IBufferOptions 
    - [Ext] options

 + [Int] IBufferStaking 
    - [Ext] claimProfit #
    - [Ext] buy #
    - [Ext] sell #
    - [Ext] profitOf

 + [Int] IBufferStakingBNB (IBufferStaking)
    - [Ext] sendProfit ($)

 + [Int] IBufferStakingIBFR (IBufferStaking)
    - [Ext] sendProfit #

 + [Int] IAccessControl 
    - [Ext] hasRole
    - [Ext] getRoleAdmin
    - [Ext] grantRole #
    - [Ext] revokeRole #
    - [Ext] renounceRole #

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

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

 + [Int] IERC165 
    - [Ext] supportsInterface

 +  ERC165 (IERC165)
    - [Pub] supportsInterface

 +  AccessControl (Context, IAccessControl, ERC165)
    - [Pub] supportsInterface
    - [Pub] hasRole
    - [Int] _checkRole
    - [Pub] getRoleAdmin
    - [Pub] grantRole #
       - modifiers: onlyRole
    - [Pub] revokeRole #
       - modifiers: onlyRole
    - [Pub] renounceRole #
    - [Int] _setupRole #
    - [Int] _setRoleAdmin #
    - [Prv] _grantRole #
    - [Prv] _revokeRole #

 + [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]  #
    - [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] _beforeTokenTransfer #
    - [Int] _afterTokenTransfer #

 +  BufferBNBPool (AccessControl, ERC20, IBNBLiquidityPool)
    - [Pub]  #
    - [Ext] setLockupPeriod #
    - [Ext] revertTransfersInLockUpPeriod #
    - [Ext] provide ($)
    - [Ext] withdraw #
    - [Ext] lock ($)
    - [Ext] unlock #
    - [Ext] send #
    - [Ext] shareOf
    - [Pub] availableBalance
    - [Pub] totalBalance
    - [Int] _beforeTokenTransfer #
    - [Pub] fullMul
    - [Pub] mulDiv
    - [Int] divCeil

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

 + [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] verifyCallResult

 +  ERC721 (Context, ERC165, IERC721, IERC721Metadata)
    - [Pub]  #
    - [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] _exists
    - [Int] _isApprovedOrOwner
    - [Int] _safeMint #
    - [Int] _safeMint #
    - [Int] _mint #
    - [Int] _burn #
    - [Int] _transfer #
    - [Int] _approve #
    - [Prv] _checkOnERC721Received #
    - [Int] _beforeTokenTransfer #

 +  ERC721Burnable (Context, ERC721)
    - [Pub] burn #

 + [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 #

 +  Ownable (Context)
    - [Pub]  #
    - [Pub] owner
    - [Pub] renounceOwnership #
       - modifiers: onlyOwner
    - [Pub] transferOwnership #
       - modifiers: onlyOwner
    - [Prv] _setOwner #

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

 +  BaseBufferBNBOptions (IBufferOptions, Ownable, ERC721, ERC721Enumerable, ERC721Burnable, AccessControl)
    - [Pub]  #
       - modifiers: ERC721
    - [Ext] setImpliedVolRate #
       - modifiers: onlyOwner
    - [Ext] setSettlementFeePercentage #
       - modifiers: onlyOwner
    - [Ext] setSettlementFeeRecipient #
       - modifiers: onlyOwner
    - [Ext] setStakingFeePercentage #
       - modifiers: onlyOwner
    - [Ext] setReferralRewardPercentage #
       - modifiers: onlyOwner
    - [Ext] setOptionCollaterizationRatio #
       - modifiers: onlyOwner
    - [Int] _create #
    - [Int] distributeSettlementFee #
    - [Pub] fees
    - [Int] getPeriodFee
    - [Int] getStrikeFee
    - [Int] getSettlementFee
    - [Int] createOptionFor #
    - [Int] _baseURI
    - [Int] _beforeTokenTransfer #
    - [Pub] supportsInterface
    - [Int] sqrt

 +  BufferBNBPredictions (BaseBufferBNBOptions)
    - [Pub]  #
       - modifiers: BaseBufferBNBOptions
    - [Pub] optionDetails
    - [Ext] create ($)
    - [Pub] execute #
    - [Ext] executeAll #
    - [Int] _transfer #