NFTSwaps Token - Smart Contract Audit Report

Summary

NFTSwaps Token Audit Report NFTSwaps is building a platform where anyone can deposit their NFT to an NFTSwaps pool and obtain BEP20 token derivatives that can be exchanged directly on PancakeSwap.

We initially analyzed NFTSwaps' token smart contract, deployed at 0xc536462e5a9fdacd4f1008a91e7daba1374c0226 in late March 2021. The team has since had a successful presale and developed the promised NFT swapping platform. This audit has been updated on May 2nd, 2021 to reflect our analysis of the NFTSwaps platform and SwapsSocks contract, reviewed at commit 802a44fcdcde3f216aaeb0046b8e99f1f9fd651d and later at commit f7b847cbaf579ec211041d2ace6ecb07973c170a on Github.

Notes on the Token Contract:
  • The total supply of the token is 2.8 million, delivered to the team upon deployment.
  • No mint functions are accessible. After deployment, the total supply can only decrease.
  • Tokens can be burned by sending them to address(0). This is accounted for in the totalSupply calculation.
  • The only ownership-restricted function is tokenRecover() which allows the owner to retrieve tokens mistakenly sent to the token contract.
  • The owner can transfer ownership to any address.
  • The contract includes the ERC-1363 approveAndCall() function, allowing for approvals and execution to occur in one call if desired.
  • The contract utilizes SafeMath to prevent overflow issues.
  • The contract utilizes an outdated version of Solidity which includes some compiler bugs.
  • Some gas optimizations can be achieved through marking functions external instead of public. As this contract is already deployed, this is informational.

Notes on the NFT Swapping Platform Contracts:
  • The platform allows any user to deposit an NFT and receive BEP20 equivelant tokens for that NFT.
  • Any user who holds NFTs can call createToken() on the router contract to create tokens to represent their NFTs as BEP20 tokens.
  • Users NFTs will be deposited in the contract, an instance of the SwapsNFTX contract will be deployed, and the user will receive one BEP20 token per NFT deposited.
  • Each instance of the SwapsNFTX contract pairs with one NFT contract.
  • The Router contract has the ability to mint and burn the BEP20 SwapsNFTX tokens in order to provide and remove tokens when NFTs are deposited and withdrawn.
  • In the reverse, the platform allows anyone to purchase the BEP20 equivelant tokens where they can they be used to redeem a randomly-selected NFT previously deposited into the platform.
  • When selecting an NFT for redeption, Chainlink is used to provide tamper-resistant verifiable randomness to the Router contract. This is the gold standard for on-chain sources of randomness. The Chainlink call value is hard-coded at 0.2 LINK; we advise making this a variable that can be updated.
  • The team can withdraw any tokens erroneously sent to the router contract.
  • Some functions can be declared external instead of public to save a minute amount of gas on each call.
  • The contract utilizes SafeMath to prevent overflows.

Notes on the SwapsSocks Contract:
  • This contract is an NFT which is intended to be backed by socks redeemable in the real world.
  • The team can mint 390 Common Socks NFTs and 10 Rare Socks NFTs. These are not effectively differentiated in each NFT, however, and can only be determined by checking the NFT's origin.
  • The team can also add users to a batch and whitelist upon deployment who will be able to mint tokens at any time. After 30 days, whitelisted users can mint NFTs.
  • A claimPhysical function is present, allowing a user to burn their NFT and claim a real-world prize. The team will provide any prizes.
  • The team can blacklist any addres disallowing them from sending or receiving NFTs.
  • The contract utilizes SafeMath and SafeTransfers to prevent overflows and ensure successful token transfers.

Audit Findings Summary:
  • No security issues were identified.
  • Ensure trust in the team if utilizing the SwapsSocks contract as the team can blacklist addresses, mint tokens, and must provide prizes.
  • Token Review Date: March 19th, 2021
  • Swapping Platform + SwapsSocks Review Date: May 2nd, 2021

External Threat Results

Vulnerability CategoryNotesResult
Arbitrary Storage WriteN/APASS
Arbitrary JumpN/APASS
Compiler BugsThe contract uses solidity 0.4.24.
We advise upgrading to 0.7.6 or above.
WARNING
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 WARNING

Details: Token Contract

ERC20 Token Graph

Multi-file Token


 ($) = payable function
 # = non-constant function
 
 Int = Internal
 Ext = External
 Pub = Public
 
 +  SafeMath 
    - [Pub] safeAdd
    - [Pub] safeSub
    - [Pub] safeMul
    - [Pub] safeDiv

 +  ERC20Interface 
    - [Pub] totalSupply
    - [Pub] balanceOf
    - [Pub] allowance
    - [Pub] transfer #
    - [Pub] approve #
    - [Pub] transferFrom #

 +  ApproveAndCallFallBack 
    - [Pub] receiveApproval #

 +  Owned 
    - [Pub]  #
    - [Pub] transferOwnership #
       - modifiers: onlyOwner
    - [Pub] acceptOwnership #

 +  NFTSwaps (ERC20Interface, Owned, SafeMath)
    - [Pub]  #
    - [Pub] totalSupply
    - [Pub] balanceOf
    - [Pub] transfer #
    - [Pub] approve #
    - [Pub] transferFrom #
    - [Pub] allowance
    - [Pub] approveAndCall #
    - [Pub] transferAnyERC20Token #
       - modifiers: onlyOwner
	   
							


Details: SwapsNFTX Contract

ERC20 Token Graph

Multi-file Token


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

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

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

 + [Lib] SafeMath 
    - [Int] add
    - [Int] sub
    - [Int] sub
    - [Int] mul
    - [Int] div
    - [Int] div
    - [Int] mod
    - [Int] mod

 + [Lib] Address 
    - [Int] isContract
    - [Int] sendValue #
    - [Int] functionCall #
    - [Int] functionCall #
    - [Int] functionCallWithValue #
    - [Int] functionCallWithValue #
    - [Prv] _functionCallWithValue #

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

 + [Int] IERC165 
    - [Ext] supportsInterface

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

 +  SwapsNFTX (ERC20, Ownable)
    - [Pub]  #
       - modifiers: ERC20
    - [Ext] factoryMint #
       - modifiers: onlyOwner
    - [Ext] factoryBurn #
       - modifiers: onlyOwner
    - [Ext] burn #
							


Details: SwapsRouter Contract

ERC20 Token Graph

Multi-file Token


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

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

 + [Int] ISwapsNFTX 
    - [Ext] factoryMint #
    - [Ext] factoryBurn #
    - [Ext] approve #
    - [Ext] transferFrom #
    - [Ext] transfer #
    - [Ext] balanceOf
    - [Ext] burn #

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

 + [Lib] SafeMath 
    - [Int] add
    - [Int] sub
    - [Int] sub
    - [Int] mul
    - [Int] div
    - [Int] div
    - [Int] mod
    - [Int] mod

 + [Lib] Address 
    - [Int] isContract
    - [Int] sendValue #
    - [Int] functionCall #
    - [Int] functionCall #
    - [Int] functionCallWithValue #
    - [Int] functionCallWithValue #
    - [Prv] _functionCallWithValue #

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

 + [Int] IERC165 
    - [Ext] supportsInterface

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

 +  SwapsNFTX (ERC20, Ownable)
    - [Pub]  #
       - modifiers: ERC20
    - [Ext] factoryMint #
       - modifiers: onlyOwner
    - [Ext] factoryBurn #
       - modifiers: onlyOwner
    - [Ext] burn #

 + [Int] IPancakeRouter01 
    - [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] IPancakeRouter02 (IPancakeRouter01)
    - [Ext] removeLiquidityETHSupportingFeeOnTransferTokens #
    - [Ext] removeLiquidityETHWithPermitSupportingFeeOnTransferTokens #
    - [Ext] swapExactTokensForTokensSupportingFeeOnTransferTokens #
    - [Ext] swapExactETHForTokensSupportingFeeOnTransferTokens ($)
    - [Ext] swapExactTokensForETHSupportingFeeOnTransferTokens #

 + [Lib] SafeMathChainlink 
    - [Int] add
    - [Int] sub
    - [Int] mul
    - [Int] div
    - [Int] mod

 + [Int] LinkTokenInterface 
    - [Ext] allowance
    - [Ext] approve #
    - [Ext] balanceOf
    - [Ext] decimals
    - [Ext] decreaseApproval #
    - [Ext] increaseApproval #
    - [Ext] name
    - [Ext] symbol
    - [Ext] totalSupply
    - [Ext] transfer #
    - [Ext] transferAndCall #
    - [Ext] transferFrom #

 +  VRFRequestIDBase 
    - [Int] makeVRFInputSeed
    - [Int] makeRequestId

 +  VRFConsumerBase (VRFRequestIDBase)
    - [Int] fulfillRandomness #
    - [Int] requestRandomness #
    - [Pub]  #
    - [Ext] rawFulfillRandomness #

 +  SwapsRouter (Ownable, VRFConsumerBase)
    - [Pub]  #
       - modifiers: VRFConsumerBase
    - [Ext] claimRandomNFT #
    - [Int] fulfillRandomness #
    - [Int] substring
    - [Int] _checkString
    - [Ext] createToken #
    - [Ext] buyTokenPancake ($)
    - [Ext] sellTokenPancake #
    - [Ext] withdrawTokens #
       - modifiers: onlyOwner
							


Details: SwapsSocks Contract

ERC20 Token Graph

Multi-file Token


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

 + [Int] IERC165 
    - [Ext] supportsInterface

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

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

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

 + [Int] IERC721Receiver 
    - [Ext] onERC721Received #

 +  ERC165 (IERC165)
    - [Int]  #
    - [Pub] supportsInterface
    - [Int] _registerInterface #

 + [Lib] SafeMath 
    - [Int] add
    - [Int] sub
    - [Int] sub
    - [Int] mul
    - [Int] div
    - [Int] div
    - [Int] mod
    - [Int] mod

 + [Lib] Address 
    - [Int] isContract
    - [Int] sendValue #
    - [Int] functionCall #
    - [Int] functionCall #
    - [Int] functionCallWithValue #
    - [Int] functionCallWithValue #
    - [Prv] _functionCallWithValue #

 + [Lib] EnumerableSet 
    - [Prv] _add #
    - [Prv] _remove #
    - [Prv] _contains
    - [Prv] _length
    - [Prv] _at
    - [Int] add #
    - [Int] remove #
    - [Int] contains
    - [Int] length
    - [Int] at
    - [Int] add #
    - [Int] remove #
    - [Int] contains
    - [Int] length
    - [Int] at

 + [Lib] EnumerableMap 
    - [Prv] _set #
    - [Prv] _remove #
    - [Prv] _contains
    - [Prv] _length
    - [Prv] _at
    - [Prv] _get
    - [Prv] _get
    - [Int] set #
    - [Int] remove #
    - [Int] contains
    - [Int] length
    - [Int] at
    - [Int] get
    - [Int] get

 + [Lib] Strings 
    - [Int] toString

 +  ERC721 (Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable)
    - [Pub]  #
    - [Pub] balanceOf
    - [Pub] ownerOf
    - [Pub] name
    - [Pub] symbol
    - [Pub] tokenURI
    - [Pub] baseURI
    - [Pub] tokenOfOwnerByIndex
    - [Pub] totalSupply
    - [Pub] tokenByIndex
    - [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] _setTokenURI #
    - [Int] _setBaseURI #
    - [Prv] _checkOnERC721Received #
    - [Prv] _approve #
    - [Int] _beforeTokenTransfer #

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

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

 +  SwapsSocks (ERC721, Ownable)
    - [Pub]  #
       - modifiers: ERC721
    - [Ext] adminMintRare #
       - modifiers: onlyOwner
    - [Ext] adminMintCommon #
       - modifiers: onlyOwner
    - [Ext] claimSocks #
    - [Ext] claimPhysical #
    - [Pub] transferFrom #
    - [Pub] safeTransferFrom #