Pulselorian

Smart Contract Audit Report

Audit Summary

Pulselorian Audit Report Pulselorian is building two new tokens and two platforms where users can stake tokens or NFTs to earn rewards.

For this audit, we reviewed the BSKR, LBSKR, and NFTStaking contracts provided to us by the project team.

Audit Findings

All findings have been resolved.
Date: February 17th, 2023.
Updated: February 23rd, 2023 to reflect updates made to the contract by the project team that resolves all Findings.

Finding #1 - NFTStaking - High (Resolved)

Description: The _creditRewards() function uses a for loop to calculate rewards for every individual user on all stakes, claims, and withdrawals.
function _creditRewards() private {
	uint256 nowTS = block.timestamp;
	for (uint256 i; i < stakersArray.length; ++i) {
		StakesMeta storage stakesMeta = stakeMap[stakersArray[i]];
		stakesMeta.unclaimedRewards += (((
			((nowTS - lastUpdateTS) * stakesMeta.stakes.length)
		) * _REWARDS_PER_HOUR) /
			countOfStakes /
			3600);
	}
	lastUpdateTS = nowTS;
}
Risk/Impact: If the total number of stakers grows too large, all stakes, claims, and withdrawals will be unable to occur due to the execution cost of the transaction exceeding the block's gas limit.
Recommendation: The team should modify the logic so that only the caller's rewards are calculated upon a stake, withdrawal, or claim. One possible solution is to add a global tracked cumulative reward amount per NFT staked and a marker for each user to track their owed rewards, similar to MasterChef functionality. Cumulative rewards should be updated before any stake, withdrawal, or claim as follows:
accumulatedRewardsPerNFT += (block.timestamp - lastUpdateTS) * _REWARDS_PER_HOUR * (1e12) / countOfStakes / 3600
lastUpdateTS = block.timestamp;
A user's claims would be executed using the following logic:
uint256 pending = (accumulatedRewardsPerNFT * stakeMap[msg.sender].stakes.length / 1e12) - rewardDebt[msg.sender];
rewardDebt[msg.sender] = (accumulatedRewardsPerNFT * stakeMap[msg.sender].stakes.length) / 1e12;
lbskrToken.transfer(msg.sender, pending);
If this logic is implemented, a user's rewardDebt must be updated to the following upon any stake made by them to avoid paying any rewards not owed to them:
rewardDebt[msg.sender] = (accumulatedRewardsPerNFT * stakeMap[msg.sender].stakes.length) / 1e12;
Resolution: The team has implemented logic similar to the above recommendation to resolve this issue.

Finding #2 - NFTStaking - High (Resolved)

Description: In the _claimRewards() function, the two parameters passed into the _penaltyFor() function will always be the same value as lastUpdateTS is updated to the current timestamp in the _creditRewards() function each time before _claimRewards() is called.
Risk/Impact: A penalty will never be charged on claims.
Recommendation: In the _claimRewards() function, the user's original stake time should be passed into the _penaltyFor() function as the first parameter in order to accurately charge a penalty for unstaking too early.
Resolution: The team has implemented the above recommendation.

Finding #3 - NFTStaking - High (Resolved)

Description: When a user initiates a withdraw, if the contract does not have a sufficient reward token balance, the user will be unable to withdraw their staked NFTs as the transfer will not execute in the _claimRewards() function.
Risk/Impact: Users' staked NFTs will be locked in the contract.
Recommendation: The team should either implement an emergency withdrawal function allowing users to withdraw their NFTs without calculating rewards, or users should be transferred the contract's remaining LBSKR token balance if there is currently not a sufficient reward balance.
Resolution: The team has implemented the above recommendation.

Finding #4 - BSKR & LBSKR - High (Resolved)

Description: The Manager can grant any user an approval to spend any number of tokens on behalf of any specified contract.
function approveContract(
	address contractAddr,
	address spender,
	uint256 amount
) external onlyManager returns (bool) {
	if (contractAddr.code.length > 0) {
		// only contract would have non-zero code length
		_approve(contractAddr, spender, amount);
	}
	return true;
}
Risk/Impact: The team can use this functionality to drain each liquidity pool of its token balance at any time.
Recommendation: The team should remove this function from the contract.
Resolution: The team has removed the above function from the contracts.

Finding #5 - BSKR - Low (Resolved)

Description: The _transfer() function transfers the remaining ETH from the contract to the owner using the transfer() function instead of the call() function.
Risk/Impact: The transfer() function uses a hardcoded gas amount of 2300, meaning transactions could run out of gas as the team receives ETH.
Recommendation: The team should use .call.value{...}("") instead as it does not have a gas limitation.
Resolution: The team has implemented the above recommendation.

Finding #6 - BSKR & LBSKR - Informational (Resolved)

Description: The following if-statements in both contract's _transfer() functions are redundant as they do not execute any logic if true:
if (_isAMMPair[from] && !_isAMMPair[to]) {
	
} else if (!_isAMMPair[from] && _isAMMPair[to]) {
	
} else if (_isAMMPair[from] && _isAMMPair[to]) {
	
}
Recommendation: The team should remove the above if-statements from both contracts for additional gas savings on each transfer.
Resolution: The team has implemented the above recommendation.

Finding #7 - LBSKR - Informational (Resolved)

Description: The following logic in the setInitialRatio() function is redundant as these values are previously set in the transaction via the _stake() function:
function setInitialRatio(uint256 amountLBSKR) external onlyOwner {	
totalLBSKRStakes = amountLBSKR;
totalBSKRStakes = amountBSKR;
totalLBSKRShares = amountLBSKR;
totalBSKRShares = amountBSKR;
Recommendation: The above logic can be removed from the setInitialRatio() function for additional gas savings on the function call.
Resolution: The team has implemented the above recommendation.

Contracts Overview

  • The contracts utilize ReentrancyGuard to prevent reentrancy attacks in applicable functions.
  • As the contracts are implemented with Solidity v0.8.0, they are safe from any possible overflows/underflows.
  • The team can upgrade the contracts at any time.
BSKR Contract:
  • The total supply is set to 1 billion tokens.
  • No public mint or burn functions are present, though the circulating supply can be decreased by sending tokens to the 0x..dead address.

  • The contract enforces a maximum transaction amount which imposes a limit to the number of tokens that can be transferred in a single transaction.
  • There is a 2% RFI fee, 0.5% Liquidity fee, 0.5% Payday fee, 1% Growth fee, and 1.5% Burn fee on all buys and sells where neither the sender nor the recipient is excluded from fees.
  • Each fee percentage is reduced by half on transfers where the LBSKR pair is either the sender or the recipient.
  • The tokens collected through the RFI fee are removed from the circulating supply; This serves as a frictionless fee redistribution that automatically benefits all token holders at the time of each transaction.
  • The Pair addresses are properly excluded from the contract's reward mechanism upon initialization to prevent theft-of-liquidity attacks. Another liquidity pool should not be used with this token as there is no mechanism to exclude addresses from rewards beyond initialization.
  • The tokens collected through the Liquidity fee are stored in the contract address. The tokens are swapped for ETH for the purpose of funding the liquidity pool when the following conditions are met:
    • The threshold number of tokens in the contract address has been reached.
    • The automatic liquidity add functionality is enabled by the team.
    • The contract is not currently performing an automatic liquidity add.
    • The caller is not initiating a buy transaction.
  • Liquidity-adds are automatically performed by selling the tokens collected as fees, pairing the received ETH with the token, and adding it as liquidity to the ETH pair.
  • The LP tokens received through this process are sent to a Sister OA address set by the team. We recommend that the team locked these newly acquired LP tokens.
  • The tokens collected through the Payday fee and Growth fee are sent to the team's Payday wallet and Growth wallets respectively.
  • The tokens collected through the Burn fee are sent to the 0x000 address.
  • The owner can airdrop any number of tokens to any address at any time.
  • A for loop is used to transfer funds for the airdrop; The team must ensure the maximum number of addresses that can be involved in a single airdrop is no more than 350 to prevent this loop from hitting the block gas limit.
  • The deployer is assigned as the contract Manager upon initialization.
  • The Manager can grant any user an approval to spend any number of BSKR tokens on behalf of any specified contract.
  • The Manager can enable/disable the UniswapV3 functionality at any time.
  • The Manager can pause/unpause the contract at any time which disables all transfers.
  • The Manager can enable/disable automatic liquidity adds at any time.
LBSKR Contract:
  • The total supply is set to 1 billion tokens.
  • The total supply is evenly split between the deployer and the Inflation address upon initialization.
  • No public mint or burn functions are present, though the circulating supply can be decreased by sending tokens to the 0x..dead address.
  • There is a 0.1% Growth fee and a 0.1% Burn fee on all buys and sells where neither the sender nor the recipient is excluded from fees.
  • The tokens collected through the Growth fee are evenly split between the team's two Growth wallets.
  • The tokens collected through the Burn fee are sent to the 0x000 address.
  • The owner can airdrop any number of tokens to any address at any time.
  • A for loop is used to transfer funds for the airdrop; The team must ensure the maximum number of addresses that can be involved in a single airdrop is no more than 350 to prevent this loop from hitting the block gas limit.

  • The owner must initiate the first stake of the contract by specifying an amount of LBSKR tokens to stake.
  • Any user can stake an amount of LBSKR tokens into the contract after the owner has initiated the first stake.
  • The number of staked tokens are swapped for BSKR and are sent to the Inflation address.
  • An amount of LBSKR shares are calculated for the user based on the ratio of the number of LBSKR tokens being staked and the total LBSKR shares of the contract to the sum of the total LBSKR tokens staked and LBSKR balance of the contract.
  • An amount of BSKR shares are calculated for the user based on the number of BSKR tokens received after the swap and the total BSKR shares for the contract to the BSKR balance of the contract before the swap occurred.
  • Users can unstake by specifying a number of tokens and their assigned Stake index.
  • A number of LBSKR tokens are sent from the contract to the user based on the calculated LBSKR reward amount.
  • A number of BSKR tokens are sent from the inflation address to the user based on the calculated BSKR reward amount.
  • An inflation amount is calculated on all stakes and unstakes which transfers an amount of LBSKR tokens from the Inflation address to this contract based on the contract's inflation rate and how many hours have passed since this functionality has previously occurred.
  • A penalty is applied on unstakes within the first year of staking depending on how many 4-week periods have passed. The LBSKR and BSKR tokens collected through the penalty are sent from the contract to the 0x000 address.
  • The owner must ensure that the contract is funded with a sufficient LBSKR Tokens balance in order to support reward distribution.
  • The deployer is assigned as the contract Manager upon initialization.
  • The Manager can grant any user an approval to spend any number of LBSKR tokens on behalf of any specified contract.
  • The Manager can enable/disable the UniswapV3 functionality at any time.
  • The Manager can pause/unpause the contract at any time which disables all transfers.
  • The owner can update the BSKR address at any time.
NFTStaking Contract:
  • This contract allows users to stake NFTs from a defined collection in order to earn LBSKR token rewards.
  • Users can stake or withdraw NFTs at any time.
  • The contract distributes rewards at a rate of 1,555 LBSKR tokens per hour.
  • A user's share of the contract's rewards is proportional to their share of total NFTs staked.
  • Rewards can be manually claimed at any time. When an NFT is withdrawn, its earned rewards are automatically claimed.
  • A reward penalty is taken if a user claims rewards for an NFT that has been staked for less than 52 weeks.
  • This penalty starts at 13% and decreases by 1% for every 4 weeks that the NFT has been staked.
  • The team should exclude this contract from LBSKR fees in order for users to be distributed their full reward amounts.
  • The owner must ensure that the contract is funded with a sufficient LBSKR Tokens balance in order to facilitate reward distribution.

Audit Results

Vulnerability Category Notes Result
Arbitrary Jump/Storage Write N/A PASS
Centralization of Control N/A PASS
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 N/A PASS
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   PASS

BSKR Contract

Smart Contract Audit - Inheritance

Smart Contract Audit - Graph


 ($) = payable function
 # = non-constant function
 
 Int = Internal
 Ext = External
 Pub = Public
 
 +  Utils 
    - [Int] _bytes32ToString
    - [Int] _callAndParseAddressReturn
    - [Int] _callAndParseUint24Return
    - [Int] _callAndParseStringReturn
    - [Int] _compare
    - [Int] _getFee
    - [Int] _getToken0
    - [Int] _getToken1
    - [Int] _penaltyFor

 + [Lib] AddressUpgradeable 
    - [Int] isContract
    - [Int] verifyCallResult
    - [Prv] _revert

 +  Initializable 
    - [Int] _disableInitializers #
    - [Int] _getInitializedVersion
    - [Int] _isInitializing

 +  ContextUpgradeable (Initializable)
    - [Int] __Context_init #
       - modifiers: onlyInitializing
    - [Int] __Context_init_unchained #
       - modifiers: onlyInitializing
    - [Int] _msgSender
    - [Int] _msgData

 +  OwnableUpgradeable (Initializable, ContextUpgradeable)
    - [Int] __Ownable_init #
       - modifiers: onlyInitializing
    - [Int] __Ownable_init_unchained #
       - modifiers: onlyInitializing
    - [Pub] owner
    - [Int] _checkOwner
    - [Pub] renounceOwnership #
       - modifiers: onlyOwner
    - [Pub] transferOwnership #
       - modifiers: onlyOwner
    - [Int] _transferOwnership #

 + [Int] IERC1822ProxiableUpgradeable 
    - [Ext] proxiableUUID

 + [Int] IBeaconUpgradeable 
    - [Ext] implementation

 + [Lib] StorageSlotUpgradeable 
    - [Int] getAddressSlot
    - [Int] getBooleanSlot

 +  ERC1967UpgradeUpgradeable (Initializable)
    - [Int] __ERC1967Upgrade_init #
       - modifiers: onlyInitializing
    - [Int] __ERC1967Upgrade_init_unchained #
       - modifiers: onlyInitializing
    - [Int] _getImplementation
    - [Prv] _setImplementation #
    - [Int] _upgradeTo #
    - [Int] _upgradeToAndCall #
    - [Int] _upgradeToAndCallUUPS #
    - [Int] _getAdmin
    - [Prv] _setAdmin #
    - [Int] _changeAdmin #
    - [Int] _getBeacon
    - [Prv] _setBeacon #
    - [Int] _upgradeBeaconToAndCall #
    - [Prv] _functionDelegateCall #

 +  UUPSUpgradeable (Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable)
    - [Int] __UUPSUpgradeable_init #
       - modifiers: onlyInitializing
    - [Int] __UUPSUpgradeable_init_unchained #
       - modifiers: onlyInitializing
    - [Ext] proxiableUUID
       - modifiers: notDelegated
    - [Ext] upgradeTo #
       - modifiers: onlyProxy
    - [Ext] upgradeToAndCall ($)
       - modifiers: onlyProxy
    - [Int] _authorizeUpgrade #

 +  PausableUpgradeable (Initializable, ContextUpgradeable)
    - [Int] __Pausable_init #
       - modifiers: onlyInitializing
    - [Int] __Pausable_init_unchained #
       - modifiers: onlyInitializing
    - [Pub] paused
    - [Int] _requireNotPaused
    - [Int] _requirePaused
    - [Int] _pause #
       - modifiers: whenNotPaused
    - [Int] _unpause #
       - modifiers: whenPaused

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

 + [Int] IUniswapV2Factory 
    - [Ext] getPair
    - [Ext] createPair #
    - [Ext] allPairsLength
    - [Ext] allPairs

 + [Int] IUniswapV2Pair 
    - [Ext] token0
    - [Ext] token1

 + [Int] IUniswapV2Router01 
    - [Ext] factory
    - [Ext] WETH
    - [Ext] WPLS
    - [Ext] addLiquidityETH ($)

 + [Int] IUniswapV2Router02 (IUniswapV2Router01)
    - [Ext] swapExactTokensForTokensSupportingFeeOnTransferTokens #
    - [Ext] swapExactTokensForETHSupportingFeeOnTransferTokens #

 + [Int] IUniswapV3Factory 
    - [Ext] getPool

 + [Int] IUniswapV3PoolImmutables 
    - [Ext] token0
    - [Ext] token1
    - [Ext] fee

 + [Int] IUniswapV3Pool (IUniswapV3PoolImmutables)

 +  Manageable (ContextUpgradeable)
    - [Pub] __Manageable_init #
       - modifiers: onlyInitializing
    - [Ext] manager
    - [Ext] transferManagement #
       - modifiers: onlyManager

 +  BaseBSKR (Utils, OwnableUpgradeable, UUPSUpgradeable, PausableUpgradeable, IERC20Upgradeable, Manageable)
    - [Pub] __BaseBSKR_init #
       - modifiers: onlyInitializing
    - [Ext]  ($)
    - [Ext]  ($)
    - [Int] __v3PairInvolved
    - [Int] _airdropTokens #
    - [Int] _approve #
    - [Int] _authorizeUpgrade #
       - modifiers: onlyOwner
    - [Int] _checkIfAMMPair #
    - [Int] _getOriginAddress #
    - [Int] _transfer #
    - [Ext] airdrop #
       - modifiers: onlyOwner
    - [Pub] allowance
    - [Ext] approve #
    - [Ext] decimals
    - [Ext] decreaseAllowance #
    - [Ext] disableUniswapV3 #
       - modifiers: onlyManager
    - [Ext] enableUniswapV3 #
       - modifiers: onlyManager
    - [Ext] increaseAllowance #
    - [Ext] name
    - [Ext] pauseContract #
       - modifiers: onlyManager
    - [Ext] symbol
    - [Ext] totalSupply
    - [Ext] transfer #
    - [Ext] transferFrom #
    - [Ext] unPauseContract #
       - modifiers: onlyManager
    - [Int] v3PairInvolved

 +  BSKR (BaseBSKR)
    - [Pub] __BSKR_init #
       - modifiers: initializer
    - [Int] _airdropTokens #
    - [Prv] _getRate
    - [Prv] _getValues
    - [Int] _isLBSKRPair #
    - [Prv] _setNoRfi #
    - [Prv] _takeFee #
    - [Int] _transfer #
       - modifiers: whenNotPaused
    - [Prv] _transferTokens #
    - [Pub] balanceOf
    - [Ext] giftReflection #
       - modifiers: whenNotPaused
    - [Ext] setSwapAndLiquifyEnabled #
       - modifiers: onlyManager
    - [Ext] stakeTransfer #

LBSKR Contract

Smart Contract Audit - Inheritance

Smart Contract Audit - Graph


 ($) = payable function
 # = non-constant function
 
 Int = Internal
 Ext = External
 Pub = Public
 
 +  Utils 
    - [Int] _bytes32ToString
    - [Int] _callAndParseAddressReturn
    - [Int] _callAndParseUint24Return
    - [Int] _callAndParseStringReturn
    - [Int] _compare
    - [Int] _getFee
    - [Int] _getToken0
    - [Int] _getToken1
    - [Int] _penaltyFor

 + [Lib] AddressUpgradeable 
    - [Int] isContract
    - [Int] verifyCallResult
    - [Prv] _revert

 +  Initializable 
    - [Int] _disableInitializers #
    - [Int] _getInitializedVersion
    - [Int] _isInitializing

 +  ContextUpgradeable (Initializable)
    - [Int] __Context_init #
       - modifiers: onlyInitializing
    - [Int] __Context_init_unchained #
       - modifiers: onlyInitializing
    - [Int] _msgSender
    - [Int] _msgData

 +  OwnableUpgradeable (Initializable, ContextUpgradeable)
    - [Int] __Ownable_init #
       - modifiers: onlyInitializing
    - [Int] __Ownable_init_unchained #
       - modifiers: onlyInitializing
    - [Pub] owner
    - [Int] _checkOwner
    - [Pub] renounceOwnership #
       - modifiers: onlyOwner
    - [Pub] transferOwnership #
       - modifiers: onlyOwner
    - [Int] _transferOwnership #

 + [Int] IERC1822ProxiableUpgradeable 
    - [Ext] proxiableUUID

 + [Int] IBeaconUpgradeable 
    - [Ext] implementation

 + [Lib] StorageSlotUpgradeable 
    - [Int] getAddressSlot
    - [Int] getBooleanSlot

 +  ERC1967UpgradeUpgradeable (Initializable)
    - [Int] __ERC1967Upgrade_init #
       - modifiers: onlyInitializing
    - [Int] __ERC1967Upgrade_init_unchained #
       - modifiers: onlyInitializing
    - [Int] _getImplementation
    - [Prv] _setImplementation #
    - [Int] _upgradeTo #
    - [Int] _upgradeToAndCall #
    - [Int] _upgradeToAndCallUUPS #
    - [Int] _getAdmin
    - [Prv] _setAdmin #
    - [Int] _changeAdmin #
    - [Int] _getBeacon
    - [Prv] _setBeacon #
    - [Int] _upgradeBeaconToAndCall #
    - [Prv] _functionDelegateCall #

 +  UUPSUpgradeable (Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable)
    - [Int] __UUPSUpgradeable_init #
       - modifiers: onlyInitializing
    - [Int] __UUPSUpgradeable_init_unchained #
       - modifiers: onlyInitializing
    - [Ext] proxiableUUID
       - modifiers: notDelegated
    - [Ext] upgradeTo #
       - modifiers: onlyProxy
    - [Ext] upgradeToAndCall ($)
       - modifiers: onlyProxy
    - [Int] _authorizeUpgrade #

 +  PausableUpgradeable (Initializable, ContextUpgradeable)
    - [Int] __Pausable_init #
       - modifiers: onlyInitializing
    - [Int] __Pausable_init_unchained #
       - modifiers: onlyInitializing
    - [Pub] paused
    - [Int] _requireNotPaused
    - [Int] _requirePaused
    - [Int] _pause #
       - modifiers: whenNotPaused
    - [Int] _unpause #
       - modifiers: whenPaused

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

 + [Int] IUniswapV2Factory 
    - [Ext] getPair
    - [Ext] createPair #
    - [Ext] allPairsLength
    - [Ext] allPairs

 + [Int] IUniswapV2Pair 
    - [Ext] token0
    - [Ext] token1

 + [Int] IUniswapV2Router01 
    - [Ext] factory
    - [Ext] WETH
    - [Ext] WPLS
    - [Ext] addLiquidityETH ($)

 + [Int] IUniswapV2Router02 (IUniswapV2Router01)
    - [Ext] swapExactTokensForTokensSupportingFeeOnTransferTokens #
    - [Ext] swapExactTokensForETHSupportingFeeOnTransferTokens #

 + [Int] IUniswapV3Factory 
    - [Ext] getPool

 + [Int] IUniswapV3PoolImmutables 
    - [Ext] token0
    - [Ext] token1
    - [Ext] fee

 + [Int] IUniswapV3Pool (IUniswapV3PoolImmutables)

 +  Manageable (ContextUpgradeable)
    - [Pub] __Manageable_init #
       - modifiers: onlyInitializing
    - [Ext] manager
    - [Ext] transferManagement #
       - modifiers: onlyManager

 +  BaseBSKR (Utils, OwnableUpgradeable, UUPSUpgradeable, PausableUpgradeable, IERC20Upgradeable, Manageable)
    - [Pub] __BaseBSKR_init #
       - modifiers: onlyInitializing
    - [Ext]  ($)
    - [Ext]  ($)
    - [Int] __v3PairInvolved
    - [Int] _airdropTokens #
    - [Int] _approve #
    - [Int] _authorizeUpgrade #
       - modifiers: onlyOwner
    - [Int] _checkIfAMMPair #
    - [Int] _getOriginAddress #
    - [Int] _transfer #
    - [Ext] airdrop #
       - modifiers: onlyOwner
    - [Pub] allowance
    - [Ext] approve #
    - [Ext] approveContract #
       - modifiers: onlyManager
    - [Ext] decimals
    - [Ext] decreaseAllowance #
    - [Ext] disableUniswapV3 #
       - modifiers: onlyManager
    - [Ext] enableUniswapV3 #
       - modifiers: onlyManager
    - [Ext] increaseAllowance #
    - [Ext] name
    - [Ext] pauseContract #
       - modifiers: onlyManager
    - [Ext] symbol
    - [Ext] totalSupply
    - [Ext] transfer #
    - [Ext] transferFrom #
    - [Ext] unPauseContract #
       - modifiers: onlyManager
    - [Int] v3PairInvolved

 + [Int] IBSKR 
    - [Ext] balanceOf
    - [Ext] stakeTransfer #

 +  Stakable (OwnableUpgradeable)
    - [Pub] __Stakable_init #
       - modifiers: onlyInitializing
    - [Int] _addStakeholder #
    - [Int] _getCurrStake
    - [Int] _stake #
    - [Int] _withdrawStake #
    - [Ext] getTotalStakeholders
    - [Ext] getTotalStakes
    - [Ext] stakesOf

 +  DSMath 
    - [Int] add
    - [Int] mul
    - [Int] rmul
    - [Int] rpow

 +  ReentrancyGuardUpgradeable (Initializable)
    - [Int] __ReentrancyGuard_init #
       - modifiers: onlyInitializing
    - [Int] __ReentrancyGuard_init_unchained #
       - modifiers: onlyInitializing

 +  LBSKR (BaseBSKR, DSMath, Stakable, ReentrancyGuardUpgradeable)
    - [Pub] __LBSKR_init #
       - modifiers: initializer
    - [Int] _airdropTokens #
    - [Prv] _calcInflation
    - [Prv] _creditInflation #
       - modifiers: isInitialRatioSet
    - [Prv] _swapTokensForTokens #
    - [Int] _transfer #
    - [Prv] _transferTokens #
       - modifiers: whenNotPaused
    - [Int] _unstakeInternal #
    - [Pub] balanceOf
    - [Ext] getBSKRAddress
    - [Ext] getCurrentBalances
       - modifiers: isInitialRatioSet
    - [Ext] penaltyIfUnstakedNow
    - [Ext] rewardsOf
    - [Ext] setBSKRAddress #
       - modifiers: onlyOwner
    - [Ext] setInitialRatio #
       - modifiers: onlyOwner
    - [Ext] stake #
       - modifiers: whenNotPaused,nonReentrant,isInitialRatioSet
    - [Ext] unstake #
       - modifiers: isInitialRatioSet,nonReentrant,whenNotPaused

NFTStaking Contract

Smart Contract Audit - Inheritance

Smart Contract Audit - Graph


 ($) = payable function
 # = non-constant function
 
 Int = Internal
 Ext = External
 Pub = Public
 
 + [Int] ILBSKR 
    - [Ext] transfer #
    - [Ext] balanceOf

 +  Initializable 
    - [Int] _disableInitializers #
    - [Int] _getInitializedVersion
    - [Int] _isInitializing

 +  ContextUpgradeable (Initializable)
    - [Int] __Context_init #
       - modifiers: onlyInitializing
    - [Int] __Context_init_unchained #
       - modifiers: onlyInitializing
    - [Int] _msgSender
    - [Int] _msgData

 +  OwnableUpgradeable (Initializable, ContextUpgradeable)
    - [Int] __Ownable_init #
       - modifiers: onlyInitializing
    - [Int] __Ownable_init_unchained #
       - modifiers: onlyInitializing
    - [Pub] owner
    - [Int] _checkOwner
    - [Pub] renounceOwnership #
       - modifiers: onlyOwner
    - [Pub] transferOwnership #
       - modifiers: onlyOwner
    - [Int] _transferOwnership #

 + [Int] IERC1822ProxiableUpgradeable 
    - [Ext] proxiableUUID

 + [Int] IBeaconUpgradeable 
    - [Ext] implementation

 + [Lib] AddressUpgradeable 
    - [Int] isContract
    - [Int] verifyCallResult
    - [Prv] _revert

 + [Lib] StorageSlotUpgradeable 
    - [Int] getAddressSlot
    - [Int] getBooleanSlot

 +  ERC1967UpgradeUpgradeable (Initializable)
    - [Int] __ERC1967Upgrade_init #
       - modifiers: onlyInitializing
    - [Int] __ERC1967Upgrade_init_unchained #
       - modifiers: onlyInitializing
    - [Int] _getImplementation
    - [Prv] _setImplementation #
    - [Int] _upgradeTo #
    - [Int] _upgradeToAndCall #
    - [Int] _upgradeToAndCallUUPS #
    - [Int] _getAdmin
    - [Prv] _setAdmin #
    - [Int] _changeAdmin #
    - [Int] _getBeacon
    - [Prv] _setBeacon #
    - [Int] _upgradeBeaconToAndCall #
    - [Prv] _functionDelegateCall #

 +  UUPSUpgradeable (Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable)
    - [Int] __UUPSUpgradeable_init #
       - modifiers: onlyInitializing
    - [Int] __UUPSUpgradeable_init_unchained #
       - modifiers: onlyInitializing
    - [Ext] proxiableUUID
       - modifiers: notDelegated
    - [Ext] upgradeTo #
       - modifiers: onlyProxy
    - [Ext] upgradeToAndCall ($)
       - modifiers: onlyProxy
    - [Int] _authorizeUpgrade #

 +  ReentrancyGuardUpgradeable (Initializable)
    - [Int] __ReentrancyGuard_init #
       - modifiers: onlyInitializing
    - [Int] __ReentrancyGuard_init_unchained #
       - modifiers: onlyInitializing

 + [Int] IERC165Upgradeable 
    - [Ext] supportsInterface

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

 +  NFTStaking (OwnableUpgradeable, UUPSUpgradeable, ReentrancyGuardUpgradeable)
    - [Pub] __NFTStaking_init #
       - modifiers: initializer
    - [Int] _authorizeUpgrade #
       - modifiers: onlyOwner
    - [Prv] _availableRewards
    - [Prv] _calculateRewards
    - [Prv] _claimRewards #
    - [Prv] _creditRewards #
    - [Prv] _penaltyFor
    - [Ext] claimRewards #
    - [Ext] penaltyIfUnstakedNow
    - [Ext] stake #
       - modifiers: nonReentrant
    - [Ext] userStakeInfo
    - [Ext] userStakedTokenIds
    - [Ext] withdraw #
       - modifiers: nonReentrant
    - [Ext] yieldDepleteEstimate

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.