BeamChef V3
Smart Contract Audit Report
Audit Summary
BeamSwap is releasing a new platform which includes staking, a voting marketplace, and a lottery.
For this audit, we reviewed the project team's BeamChefV3, FarmBooster, FarmBoostMarketplace, and BeamswapLottery contracts at commit 942c067d5db55ad79a8b8ccabf97aacbd01c0f94 and RandomNumberGenerator contract at commit 32059d548dcf25cdd34dcdf329cc79950cbfa088 on the team's private GitHub repository.
We previously reviewed the project team's Decentralized Exchange here.
Audit Findings
All findings have been resolved, though some centralized aspects are present.
Date: November 20th, 2023.
Updated: December 6th, 2023 to include the FarmBooster contract and reflect changes from commit 718e86127990422624ee20c75a6f1ff4a928d540 to commit b82bedde26a848ecc4527f104e20de6e725297c8 on the team's private GitHub repository.
Updated: December 26th, 2023 to include the FarmBoostMarketplace and BeamswapLottery contracts and reflect changes from commit b82bedde26a848ecc4527f104e20de6e725297c8 to commit bfeab881041abf555f70f0349983b3039721f46e on the team's private GitHub repository.
Updated: January 4th, 2024 to reflect changes from commit bfeab881041abf555f70f0349983b3039721f46e to commit 942c067d5db55ad79a8b8ccabf97aacbd01c0f94 on the team's private GitHub repository.
Updated: January 12th, 2024 to include the RandomNumberGenerator contract at commit 32059d548dcf25cdd34dcdf329cc79950cbfa088.
Updated: January 15th, 2024 to include reflect changes to the RandomNumberGenerator contract from commit 32059d548dcf25cdd34dcdf329cc79950cbfa088 to commit e72a8bd908ba9126b4203e49ba3222523f1c4f0b.
Updated: January 25th, 2023 to reflect all changes to commit 1b977a409d002e25fab99ea6656fe5ec3085c52f.Finding #1 - BeamChefV3 - High (Resolved)
Description: A pool is not updated when it is voted or unvoted on. A pool's votes impact its share of community allocation points, which are used to calculate its accumulated rewards over time. If a pool's votes are updated, its rewards up to the time of a vote adjustment must be calculated to ensure that incremented or decremented votes are not included during the window from its last update to the time of the vote adjustment.
Risk/Impact: A pool's rewards will be inaccurate if voting occurs without a pool update. This can lead to the contract owing more rewards than intended, or users receiving less rewards than anticipated.
Recommendation: The_updatePool()
function should be called anytime a pool's vote count is adjusted.
Resolution: The team has implemented the above recommendation.
Finding #2 - BeamChefV3 - High (Resolved)
Description: The decreaseAllocation() function incorrectly increments the total community allocation points instead of decrementing them:
function decreaseAllocation( uint256 _pid, uint256 _allocPointCommunity ) internal { if (block.timestamp >= lastUpdatedTimeVotes + 7 days) { _massUpdatePools(); lastUpdatedTimeVotes = block.timestamp; } totalAllocPointCommunity = totalAllocPointCommunity + _allocPointCommunity; poolInfo[_pid].allocPointCommunity = poolInfo[_pid].allocPointCommunity - _allocPointCommunity; }
Risk/Impact: Each pool's accumulated community rewards are determined by its individual community allocation points in relation to the total community allocation points. An incorrectly large total community allocation point value will result in each pool receiving a smaller percentage of total community rewards than intended.
Recommendation: ThetotalAllocPointCommunity
variable should instead be decremented in the decreaseAllocation() function.
Resolution: The team has implemented the above recommendation.
Finding #3 - BeamChefV3 - High (Resolved)
Description: If a user executes theunVotePool()
function and specifies a pool ID that they did not originally vote for, they will be permitted to vote again. Since theuserInfo[_pid][_user]
mapping contains separate user information for each pool, a user'svotedID
will be 0 whenunVotePool()
is called in this scenario.
Risk/Impact: A user can multiply their voting power by unvoting and subsequently voting again, specifying a separate pool than the one originally voted for when unvoting and voting. This would unfairly increase the community rewards received by the selected pools.function unVotePool(uint256 _pid) external { address _user = msg.sender; require(voted[_user], "not voted"); UserInfo storage user = userInfo[_pid][_user]; redeemVote(_user, user.votedID); voted[_user] = false; }
Recommendation: A new mapping should be created to link a user address directly to theirvotedID
to avoid a user having a separatevotedID
for each pool. When unvoting, the user should not need to specify a pool ID; the mapping should be used to automatically remove their votes from the correct pool.
Resolution: The team has resolved this issue with the addition of the FarmBooster contract.
Finding #4 - BeamChefV3 - High (Resolved)
Description: A user can vote multiple times using the same stGLINT balance by voting, transferring their stGLINT to a different address, and subsequently voting again as the receiver of the transfer.
Risk/Impact: A user can gain infinite voting power by repeatedly voting and transferring their stGLINT to different addresses owned by them.
Recommendation: The project team should consider restructuring the voting logic or the stGLINT token logic. One option would be to require users to stake their stGLINT into this contract in order to use it to vote. Another solution is to update the logic of both this contract and the stGLINT contract to automatically unvote on a user's behalf whenever they transfer tokens.
Resolution: The team has resolved this issue with the addition of the FarmBooster contract.
Finding #5 - RandomNumberGenerator - High (Resolved)
Description: Any user can request a random number that will be used by the Lottery contract. Any new fulfillment overwrites the previously fulfilled request, allowing the winning numbers to be rerolled until the project team ends the current Lottery round.
Risk/Impact: If a random number request produces non-winning numbers for a user, they can abuse this contract by initiating another randomness request to replace the existing winning numbers as long as the project team has not selected a winner. This can be repeated until a user receives a desirable number.
Recommendation: Only the BeamSwapLottery contract should be permitted to request a random number through this contract.
Resolution: The team has implemented the above recommendation.
Finding #6 - RandomNumberGenerator - Low (Resolved)
Description: ThegasPrice
variable can be updated by the Operator address, but does not serve a purpose after contract creation. TheMIN_FEE
variable, which is initially calculated asFULFILLMENT_GAS_LIMIT * gasPrice
, is not updated oncegasPrice
is changed.
Risk/Impact: The Operator will be unable to update the minimum fee requirement for a random number request.
Recommendation: TheMIN_FEE
variable should be updated in thesetGasPrice()
function.
Resolution: The team has implemented the above recommendation.
Finding #7 - RandomNumberGenerator - Informational (Resolved)
Description: A block's collator can choose omit a request fulfillment transaction if its random number produced is not desirable for them, allowing a new number to be generated by the next collator. However, risk is very low as the collator can only potentially benefit if they are chosen for the block out of 72 collators, and participating in the Lottery. This can be repeated if the collator has control of multiple consecutive blocks, but at the cost of increasing block reward forfeitures.
Risk/Impact: A malicious collator can omit a fulfillment transaction in order for a new random number to be generated, potentially manipulating a Lottery's results to be more favorable for them.
Recommendation: The team may want to add the ability to adjust the minimum delay before a request can be fulfilled. If one of the Lottery's jackpots begins to exceed a blocks reward and the team suspects any malicious collators, they can consider increasing this minimum delay. As the delay increases, the collator who will be chosen to produce a block becomes less certain, further mitigating risk of manipulation.
Resolution: The team has implemented the above recommendation.
Finding #8 - BeamChefV3 - Informational (Resolved)
Description: ThependingTokens()
function does not account for the dev fee when calculating pending community rewards. There is no direct impact within this contract; however, this contract will return incorrect pending reward values to other contracts relying on this function.
Recommendation: Theuint256 glintRewardCommunity = pool.allocPointCommunity != 0 ? ((multiplier * beamPerSecCommunity) * pool.allocPointCommunity) / totalAllocPointCommunity : 0;
glintRewardCommunity
value should be multiplied by the non-fee percentage.
Resolution: The team has implemented the above recommendation.
Finding #9 - BeamChefV3 - Informational (Resolved)
Description: ThePoolInfo
Struct'scountDepositAmountAsVotingPower
field is never used.
Recommendation: This field can be removed for gas savings on function calls.
Resolution: The team has implemented the above recommendation.
Finding #10 - BeamChefV3 - Informational (Resolved)
Description: ThefarmBooster
variable is not declared immuntable but never updated after deployment.
Recommendation: This variable can be decalred immutable for gas savings on various function calls.
Resolution: The team has implemented the above recommendation.
Finding #11 - FarmBoostMarketPlace - Informational (Resolved)
Description: The following statement exists in the offerVotingPower() function:
Recommendation: This statement can be updated to the following for gas savings on each call:require( this.getAllActiveOffersForUser(msg.sender).length == 0, "user has active offer" );
Resolution: The team has implemented the above recommendation.require(userActiveOfferIds[msg.sender].length() == 0, "user has active offer"); );
Finding #12 - BeamswapLottery - Informational (Resolved)
Description: ThewglmrToken
variable is declared but never used meaningfully.
Recommendation: Any mentions of this variable can be removed for gas savings on deployment and owner withdrawals.
Resolution: The team has implemented the above recommendation.
Contracts Overview
BeamChefV3 Contract:
- These contracts utilizes ReentrancyGuard to protect against reentrancy attacks in applicable functions.
- As the contracts are implemented with Solidity v0.8, they are safe from any possible overflows/underflows.
FarmBooster Contract:
- Any user may deposit various LP tokens into staking pools to earn rewards in Beam tokens, stGLINT tokens, and potentially other rewards from additional Rewarder contracts.
- Users may additionally provide a signed message to the contract allowing them to approve and deposit in one transaction to save on gas fees.
- A pool's reward rate is determined by its allocation points and community allocation points, as well as by the contract's rewards emission rate and community rewards emission rate.
- A pool's allocation and community allocation points in relation to the totals of each point type determine the percentage of the total accumulated rewards and community rewards it is distributed.
- Users will receive a portion of both a pool's rewards and community rewards based on their share of the pool's deposited LP tokens.
- A "stGLINT percentage" of all pending Beam rewards will additionally be minted to users as stGLINT tokens.
- Rewards in other tokens are determined by the pool's associated Rewarder contracts.
- Users may only claim their rewards once per "harvest" period. Each pool has its own harvest period and may vary between pools, with a maximum allowed harvest period of 14 days.
- On deposits and withdrawals, pending rewards are calculated and minted to the user, if eligible.
- Users may additionally provide a list of up to 25 pool IDs to harvest any available rewards from each specified pool.
- A deposit fee of up to 10% which is transferred to the Fee address controlled by the team. Each pool has its own deposit fee and may vary between pools.
- A Dev fee of up to 20% is taken from distributed stGLINT and Beam rewards and minted to a Dev wallet controlled by the team.
- The user may also trigger an emergency withdrawal, which will transfer all the user's deposited LP tokens to their wallet address, without calculating rewards.
- This contract also allows users to vote on voting-enabled pools to increase their share of community rewards.
- Users are intended to vote through the associated stGLINT and FarmBooster contracts.
- A user's votes directly increase a pool's community allocation points.
- All pool rewards are only updated after a user's vote if the "vote delay" has passed since the last pool reward update from voting has occurred. As a result, voting rewards may be slightly skewed due in favor of gas savings.
- The owner may update the vote delay to any length at any time.
- The owner may update the rewards emission rate and community rewards emission rate to any values at any time.
- The owner may update a pool's allocation points, voting flag, stGLINT percentage, voting eligibility, and Rewarders to any values at any time.
- The owner may update the a pool's harvest interval to up to 14 days at any time.
- The owner may update the Dev and Fee addresses at any time.
- The owner may update the Dev fee to up to 20% and a pool's deposit fee to up to 10% at any time.
- The owner may update a pool's stGLINT percentage to any value at any time.
FarmBoostMarketPlace Contract:
- This contract is used to facilitate voting in the associated BeamChefV3 contract.
- The stGLINT contract address is intended to call this contract's allocate or deallocate functionality to adjust each users' tracked voting power any time their balances are updated.
- Only the stGLINT contract address can allocate and deallocate, providing a user, vote amount, and a pool ID.
- When an allocation is executed, the specified user's total votes are delegated to the specified BeamChefV3 pool.
- A deallocation removes a user's total votes from the specified BeamChefV3 pool.
- Any allocation or deallocation increments or decrements their tracked vote total.
- An allocation cannot be executed on a pool that is does not have voting enabled, or if a user is currently voting for a different pool.
- A deallocation cannot be executed for a user if they have not voted yet, or if the specified pool is not the one they are currently voting for.
- The BeamChefV3 address can be updated by the owner at any time.
- The project team must ensure that allocations and deallocations are correctly executed by the stGLINT contract and cannot be abused.
BeamswapLottery Contract:
- This contract allows users to rent and purchase voting power for a custom amount of time.
- When creating a listing, the seller must offer a nonzero number of votes, a duration between 1 week and 1 year, and a purchase price in the form of the blockchain's native currency of at least 1 token.
- When the listing is created, stGLINT for voting is transferred from the seller to this contract.
- A user cannot create a listing if they have voted through the FarmBooster contract.
- A user can purchase an active listing at any time, specifying the BeamChefV3 pool that they would like rented votes to be dedicated towards.
- When purchasing, the user must provide the listing's exact payment amount in the form of the blockchain's native currency.
- A "platform fee" is taken from the payment amount and transferred to the Fee Manager address; the remainder is transferred to the seller.
- The listing's duration is immediately activated upon purchase, and the votes are cast towards the specified BeamChefV3 pool on behalf of the seller.
- While a seller can create multiple listings, only one listing can be actively rented at a time.
- A seller can end their listing to reclaim their tokens and votes once the listing's duration has expired from the time of its purchase. The listing is subsequently deleted.
- A seller can cancel a listing at any time if it has not been purchased; their deposited stGLINT is then transferred back to them.
- The owner can withdraw any of the blockchain's native currency or any token from this contract at any time.
- The owner can update the platform fee to up to 20% at any time.
- The owner can update the Fee Manager address at any time.
RandomNumberGenerator Contract:
- The Operator can begin the first lottery at any time, and any additional lottery rounds once the most recent one has been marked as claimable.
- An end time, ticket price, "discount divisor", and treasury fee are all specified upon creation.
- Users can purchase up to the contract's "maximum buy or claim amount" at a time while a lottery is open, specifying the ticket numbers they wish to purchase.
- Provided ticket numbers must be in the range of 1 million to 1,999,999, inclusive.
- The discount divisor decreases the price per ticket as the number of tickets purchased at once increases, rewarding users buying in bulk.
- A ticket purchaser must provide exact payment in the form of the blockchain's native currency when buying.
- Once a lottery round's end time has been reached, the Operator can close the lottery which initiates a random number request to the associated RandomNumberGenerator contract.
- The Operator can draw the winning numbers once the RandomNumberGenerator contract has selected a number for the closed lottery.
- A treasury fee is taken from the total amount collected and transferred to the treasury address.
- The total amount distributed from each lottery is equal to the amount collected minus the treasury fee.
- The owner or Injector address can also inject additional funds into an open lottery to add to the total prizes.
- Once drawn, users can claim winnings by providing winning ticket IDs and their prize pool bracket, up to the maximum buy or claim amount at once.
- The last 6 digits of each ticket number are used to determine its winnings.
- Each ticket can qualify for a single prize pool based on the number of digits in a row, starting from the left-most digit, that match the 6 winning ticket numbers.
- A prize pool's funds are divided into the total number of tickets that have qualified for the pool.
- The distribution percentages for each prize pool are decided by the Operator when they are established.
- Contracts are not permitted to purchase or claim tickets.
- The owner can update the maximum and minimum ticket price at any time.
- The Operator can set a lottery's length to any value between 20 hours and 7 days and 5 minutes upon creation.
- The Operator can set a lottery's treasury fee to up to 30% upon creation.
- The owner can update the RandomNumberGenerator address at any time.
- The owner can update the maximum number of tickets that can be purchased or claimed at once at any time.
- The project team must ensure that the discount divisor remains significantly larger than the maximum ticket purchase limit to avoid abuse.
- The owner can withdraw any ERC-20 tokens, excluding WGLMR, from the contract at any time.
- The owner can update the Operator, Treasury, and Injector addresses at any time.
- This contract uses Moonbeam's randomness precompile to generate random numbers used to choose BeamSwap Lottery winners.
- The Operator or Lottery contract can request a random number to be used by the Lottery at any time.
- A minimum fee must be provided upon request.
- After a minimum the contract's minimum delay has passed, the request can be fulfilled by any user.
- The Operator can update the contract's gas price at any time.
- The Operator can transfer the Operator role to another address at any time.
- The Operator can update the minimum required fee and the refunded address for a fulfillment at any time.
- The Operator can update the minimum delay before a request can be fulfilled at any time.
- The Operator can update the BeamSwapLottery address at any time.
- The Operator can withdraw any native currency or tokens from the contract at any time.
Audit Results
Vulnerability Category | Notes | Result |
---|---|---|
Arbitrary Jump/Storage Write | N/A | PASS |
Centralization of Control |
|
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 | 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 |
BeamChefV3 Contract
($) = payable function
# = non-constant function
Int = Internal
Ext = External
Pub = Public
Int = Internal
Ext = External
Pub = Public
+ Context
- [Int] _msgSender
- [Int] _msgData
+ Ownable (Context)
- [Pub] #
- [Pub] owner
- [Pub] renounceOwnership #
- modifiers: onlyOwner
- [Pub] transferOwnership #
- modifiers: onlyOwner
- [Int] _transferOwnership #
+ ReentrancyGuard
- [Pub] #
+ [Lib] Address
- [Int] isContract
- [Int] sendValue #
- [Int] functionCall #
- [Int] functionCall #
- [Int] functionCallWithValue #
- [Int] functionCallWithValue #
- [Int] functionStaticCall
- [Int] functionStaticCall
- [Int] functionDelegateCall #
- [Int] functionDelegateCall #
- [Int] verifyCallResult
+ [Int] IBoringERC20
- [Ext] mint #
- [Ext] totalSupply
- [Ext] balanceOf
- [Ext] allowance
- [Ext] approve #
- [Ext] permit #
+ [Int] IMultipleRewards
- [Ext] onBeamReward #
- [Ext] pendingTokens
- [Ext] rewardToken
- [Ext] poolRewardsPerSec
+ [Lib] BoringERC20
- [Int] returnDataToString
- [Int] safeSymbol
- [Int] safeName
- [Int] safeDecimals
- [Int] safeTransfer #
- [Int] safeTransferFrom #
+ [Int] IBeamSwapPair
- [Ext] initialize #
- [Ext] permit #
+ [Int] IERC20
- [Ext] totalSupply
- [Ext] balanceOf
- [Ext] transfer #
- [Ext] allowance
- [Ext] approve #
- [Ext] transferFrom #
+ [Int] IstGlint (IERC20)
- [Ext] usageAllocations
- [Ext] allocateFromUsage #
- [Ext] convertTo #
- [Ext] deallocateFromUsage #
- [Ext] isTransferWhitelisted
+ BeamChefV3 (Ownable, ReentrancyGuard)
- [Pub] #
- [Pub] startFarming #
- modifiers: onlyOwner
- [Ext] poolLength
- [Pub] add #
- modifiers: onlyOwner
- [Pub] set #
- modifiers: onlyOwner,validatePoolByPid
- [Ext] pendingTokens
- modifiers: validatePoolByPid
- [Ext] poolRewardsPerSec
- modifiers: validatePoolByPid
- [Ext] poolRewarders
- modifiers: validatePoolByPid
- [Pub] canHarvest
- modifiers: validatePoolByPid
- [Ext] massUpdatePools #
- modifiers: nonReentrant
- [Int] _massUpdatePools #
- [Ext] updatePool #
- modifiers: nonReentrant
- [Int] increaseAllocation #
- [Int] decreaseAllocation #
- [Int] vote #
- [Int] redeemVote #
- [Int] _updatePool #
- modifiers: validatePoolByPid
- [Pub] depositWithPermit #
- modifiers: nonReentrant,validatePoolByPid
- [Pub] deposit #
- modifiers: nonReentrant
- [Int] _deposit #
- modifiers: validatePoolByPid
- [Pub] withdraw #
- modifiers: nonReentrant,validatePoolByPid
- [Pub] emergencyWithdraw #
- modifiers: nonReentrant
- [Int] payOrLockupPendingGlint #
- [Int] safeGlintTransfer #
- [Int] updateVotePool #
- [Pub] getTotalVotePower
- [Ext] votePool #
- [Ext] unVotePool #
- [Pub] updateAllocPoint #
- modifiers: onlyOwner
- [Pub] updateEmissionRate #
- modifiers: onlyOwner
- [Pub] updateEmissionRateCommunity #
- modifiers: onlyOwner
- [Ext] poolTotalLp
- [Pub] harvestMany #
- modifiers: nonReentrant
- [Pub] setDevAddress #
- modifiers: onlyOwner
- [Pub] setDevPercent #
- modifiers: onlyOwner
- [Pub] setFeeAddress #
- modifiers: onlyOwner
- [Ext] setXGlintRates #
- modifiers: onlyOwner
- [Pub] setXGlintRate #
- modifiers: onlyOwner
- [Pub] getGlintPerSec
FarmBooster Contract
($) = payable function
# = non-constant function
Int = Internal
Ext = External
Pub = Public
+ Context
- [Int] _msgSender
- [Int] _msgData
+ Ownable (Context)
- [Pub] #
- [Pub] owner
- [Pub] renounceOwnership #
- modifiers: onlyOwner
- [Pub] transferOwnership #
- modifiers: onlyOwner
- [Int] _transferOwnership #
+ [Int] IERC20
- [Ext] totalSupply
- [Ext] balanceOf
- [Ext] transfer #
- [Ext] allowance
- [Ext] approve #
- [Ext] transferFrom #
+ [Lib] Address
- [Int] isContract
- [Int] sendValue #
- [Int] functionCall #
- [Int] functionCall #
- [Int] functionCallWithValue #
- [Int] functionCallWithValue #
- [Int] functionStaticCall
- [Int] functionStaticCall
- [Int] functionDelegateCall #
- [Int] functionDelegateCall #
- [Int] verifyCallResult
+ [Lib] SafeERC20
- [Int] safeTransfer #
- [Int] safeTransferFrom #
- [Int] safeApprove #
- [Int] safeIncreaseAllowance #
- [Int] safeDecreaseAllowance #
- [Prv] _callOptionalReturn #
+ ReentrancyGuard
- [Pub] #
+ [Lib] EnumerableSet
- [Prv] _add #
- [Prv] _remove #
- [Prv] _contains
- [Prv] _length
- [Prv] _at
- [Prv] _values
- [Int] add #
- [Int] remove #
- [Int] contains
- [Int] length
- [Int] at
- [Int] values
- [Int] add #
- [Int] remove #
- [Int] contains
- [Int] length
- [Int] at
- [Int] values
- [Int] add #
- [Int] remove #
- [Int] contains
- [Int] length
- [Int] at
- [Int] values
+ [Int] IstGlintUsage
- [Ext] allocate #
- [Ext] deallocate #
+ [Int] IBeamChefV3
- [Ext] votePool #
- [Ext] unVotePool #
- [Ext] updateVotePool #
- [Ext] isPoolVoteable
- [Ext] votePoolMarket #
+ FarmBooster (Ownable, ReentrancyGuard, IstGlintUsage)
- [Pub] #
- [Ext] ($)
- [Ext] allocate #
- modifiers: nonReentrant,stGlintTokenOnly
- [Ext] deallocate #
- modifiers: nonReentrant,stGlintTokenOnly
- [Int] _updateUser #
- [Ext] getVotingPower
- [Ext] setBeamChefV3 #
- modifiers: onlyOwner
- [Ext] hasUserVoted
FarmBoostMarketplace Contract
($) = payable function
# = non-constant function
Int = Internal
Ext = External
Pub = Public
+ Context
- [Int] _msgSender
- [Int] _msgData
+ Ownable (Context)
- [Pub] #
- [Pub] owner
- [Pub] renounceOwnership #
- modifiers: onlyOwner
- [Pub] transferOwnership #
- modifiers: onlyOwner
- [Int] _transferOwnership #
+ [Int] IERC20
- [Ext] totalSupply
- [Ext] balanceOf
- [Ext] transfer #
- [Ext] allowance
- [Ext] approve #
- [Ext] transferFrom #
+ [Lib] Address
- [Int] isContract
- [Int] sendValue #
- [Int] functionCall #
- [Int] functionCall #
- [Int] functionCallWithValue #
- [Int] functionCallWithValue #
- [Int] functionStaticCall
- [Int] functionStaticCall
- [Int] functionDelegateCall #
- [Int] functionDelegateCall #
- [Int] verifyCallResult
+ [Lib] SafeERC20
- [Int] safeTransfer #
- [Int] safeTransferFrom #
- [Int] safeApprove #
- [Int] safeIncreaseAllowance #
- [Int] safeDecreaseAllowance #
- [Prv] _callOptionalReturn #
+ ReentrancyGuard
- [Pub] #
+ [Lib] EnumerableSet
- [Prv] _add #
- [Prv] _remove #
- [Prv] _contains
- [Prv] _length
- [Prv] _at
- [Prv] _values
- [Int] add #
- [Int] remove #
- [Int] contains
- [Int] length
- [Int] at
- [Int] values
- [Int] add #
- [Int] remove #
- [Int] contains
- [Int] length
- [Int] at
- [Int] values
- [Int] add #
- [Int] remove #
- [Int] contains
- [Int] length
- [Int] at
- [Int] values
+ [Int] IBeamChefV3
- [Ext] votePool #
- [Ext] unVotePool #
- [Ext] updateVotePool #
- [Ext] isPoolVoteable
- [Ext] votePoolMarket #
+ [Int] IFarmBooster
- [Ext] hasUserVoted
+ FarmBoostMarketplace (Ownable, ReentrancyGuard)
- [Pub] #
- [Ext] ($)
- [Ext] offerVotingPower #
- modifiers: nonReentrant
- [Ext] cancelOffer #
- modifiers: nonReentrant
- [Ext] acceptVotingPowerOffer ($)
- modifiers: nonReentrant
- [Ext] endOffer #
- modifiers: nonReentrant
- [Ext] getActiveOfferIds
- [Ext] getTotalActiveOffers
- [Ext] getAllActiveOffersForUser
- [Ext] getAllActiveOffers
- [Ext] withdrawGLMR #
- modifiers: onlyOwner
- [Pub] getVotingPower
- [Int] safeTransferGLMR #
- [Pub] emergencyWithdraw #
- modifiers: nonReentrant,onlyOwner
- [Ext] setPlatformFee #
- modifiers: onlyOwner
- [Ext] setFeeManager #
- modifiers: onlyOwner
BeamSwapLottery Contract
($) = payable function
# = non-constant function
Int = Internal
Ext = External
Pub = Public
+ Context
- [Int] _msgSender
- [Int] _msgData
+ Ownable (Context)
- [Pub] #
- [Pub] owner
- [Pub] renounceOwnership #
- modifiers: onlyOwner
- [Pub] transferOwnership #
- modifiers: onlyOwner
- [Int] _transferOwnership #
+ ReentrancyGuard
- [Pub] #
+ [Int] IERC20
- [Ext] totalSupply
- [Ext] balanceOf
- [Ext] transfer #
- [Ext] allowance
- [Ext] approve #
- [Ext] transferFrom #
+ [Lib] Address
- [Int] isContract
- [Int] sendValue #
- [Int] functionCall #
- [Int] functionCall #
- [Int] functionCallWithValue #
- [Int] functionCallWithValue #
- [Int] functionStaticCall
- [Int] functionStaticCall
- [Int] functionDelegateCall #
- [Int] functionDelegateCall #
- [Int] verifyCallResult
+ [Lib] SafeERC20
- [Int] safeTransfer #
- [Int] safeTransferFrom #
- [Int] safeApprove #
- [Int] safeIncreaseAllowance #
- [Int] safeDecreaseAllowance #
- [Prv] _callOptionalReturn #
+ [Int] IRandomNumberGenerator
- [Ext] getRandomNumber ($)
- [Ext] viewLatestLotteryId
- [Ext] viewRandomResult
+ [Int] IBeamswapLottery
- [Ext] buyTickets ($)
- [Ext] claimTickets #
- [Ext] closeLottery ($)
- [Ext] drawFinalNumberAndMakeLotteryClaimable #
- [Ext] injectFunds ($)
- [Ext] startLottery #
- [Ext] viewCurrentLotteryId #
- [Ext] viewUserInfoForLotteryId
+ [Int] IWGLMR
- [Ext] deposit ($)
- [Ext] transfer #
- [Ext] withdraw #
+ BeamswapLottery (ReentrancyGuard, IBeamswapLottery, Ownable)
- [Ext] ($)
- [Pub] #
- [Ext] buyTickets ($)
- modifiers: notContract,nonReentrant
- [Ext] claimTickets #
- modifiers: notContract,nonReentrant
- [Ext] closeLottery ($)
- modifiers: onlyOperator,nonReentrant
- [Ext] drawFinalNumberAndMakeLotteryClaimable #
- modifiers: onlyOperator,nonReentrant
- [Ext] changeRandomGenerator #
- modifiers: onlyOwner
- [Ext] injectFunds ($)
- modifiers: onlyOwnerOrInjector
- [Ext] startLottery #
- modifiers: onlyOperator
- [Ext] recoverWrongTokens #
- modifiers: onlyOwner
- [Ext] setMinAndMaxTicketPriceInWglmr #
- modifiers: onlyOwner
- [Ext] setMaxNumberTicketsPerBuy #
- modifiers: onlyOwner
- [Ext] setOperatorAndTreasuryAndInjectorAddresses #
- modifiers: onlyOwner
- [Ext] calculateTotalPriceForBulkTickets
- [Ext] viewCurrentLotteryId
- [Ext] viewLottery
- [Ext] viewNumbersAndStatusesForTicketIds
- [Ext] viewRewardsForTicketId
- [Ext] viewUserInfoForLotteryId
- [Int] _calculateRewardsForTicketId
- [Int] _calculateTotalPriceForBulkTickets
- [Int] _isContract
- [Int] safeTransferETH #
RandomNumberGenerator Contract
($) = payable function
# = non-constant function
Int = Internal
Ext = External
Pub = Public
+ [Int] Randomness
- [Ext] relayEpochIndex
- [Ext] requiredDeposit
- [Ext] getRequestStatus
- [Ext] getRequest
- [Ext] requestLocalVRFRandomWords #
- [Ext] requestRelayBabeEpochRandomWords #
- [Ext] fulfillRequest #
- [Ext] increaseRequestFee #
- [Ext] purgeExpiredRequest #
+ RandomnessConsumer
- [Int] fulfillRandomWords #
- [Ext] rawFulfillRandomWords #
+ [Int] IERC20
- [Ext] totalSupply
- [Ext] balanceOf
- [Ext] transfer #
- [Ext] allowance
- [Ext] approve #
- [Ext] transferFrom #
+ [Lib] Address
- [Int] isContract
- [Int] sendValue #
- [Int] functionCall #
- [Int] functionCall #
- [Int] functionCallWithValue #
- [Int] functionCallWithValue #
- [Int] functionStaticCall
- [Int] functionStaticCall
- [Int] functionDelegateCall #
- [Int] functionDelegateCall #
- [Int] verifyCallResult
+ [Lib] SafeERC20
- [Int] safeTransfer #
- [Int] safeTransferFrom #
- [Int] safeApprove #
- [Int] safeIncreaseAllowance #
- [Int] safeDecreaseAllowance #
- [Prv] _callOptionalReturn #
+ [Int] IBeamswapLottery
- [Ext] buyTickets ($)
- [Ext] claimTickets #
- [Ext] closeLottery ($)
- [Ext] drawFinalNumberAndMakeLotteryClaimable #
- [Ext] injectFunds ($)
- [Ext] startLottery #
- [Ext] viewCurrentLotteryId #
- [Ext] viewUserInfoForLotteryId
+ RandomNumberGenerator (RandomnessConsumer)
- [Pub] ($)
- modifiers: RandomnessConsumer
- [Ext] ($)
- [Pub] getRandomNumber ($)
- [Pub] fulfillRequest #
- [Int] fulfillRandomWords #
- [Pub] setGasPrice #
- [Pub] setOperator #
- [Ext] viewLatestLotteryId
- [Ext] viewRandomResult
- [Pub] setBeamSwapLottery #
- [Pub] setFulfillmentGasLimit #
- [Ext] withdrawRewardsEmergency #
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.