LetsGo Finance Token & Pool Contracts - Smart Contract Audit Report
Summary
LetsGo Finance is building a decentralized fundraising platform for artists, independent media, non-profits, communities and enterprise.
For this audit, we reviewed the project's token contract and MasterChef, Venus, and Ego Pools. We also reviewed the team's TWAP oracle implementation using code provided to us by the team.
Notes on the Contracts:The initial supply of the Ego token is 0. The token cannot be minted after deployment. Any user may burn their own tokens to reduce the total supply. No other ownership-restricted functions are present. There are no fees on transfers of the token. We reviewed three of the project's Pool contracts for this audit - the EgoPool, the MasterChefPool, and the VenusPool. Users can stake various tokens in each pool in order to earn rewards in the form of the project's native token. Deposits that are made into each pool will be forwarded to different external contracts or protocols in order to earn yield on deposited assets. Please note we hae not reviewed the external protocols used to earn yield. When users stake into the contract, they designate a Celebrity and a percentage of earned rewards to be alloated to the Celebrity. Celebrity rewards will be subject to a platform fee as set and updatable by the team. Stakers can claim their rewards at any time. Users who are designated as 'Celerbrities' can Rewards to be sent to users are stored in a Vault contract, which has no functions but allows its deployer (the Pools) to transfer tokens from it. The team can withdraw all rewards at any time. The team can withdraw the rewards from the contract at any time. The MAX_INT variable could be declared constant to save gas both on deployment and each reference. The calculateCelebrityNetAssetReward() function could be declared external instead of public to save some gas on each call. The PancakePriceProvider contract is used to get raw price data from Pancakeswap pairs. The current mechanism used to get prices is suseptible to flash loan attacks. We advise upgrading this contract to use time-weighted average prices (a 'TWAP' mechanism). By upgrading the contract to use prices that are time-weighted, the project can obtain pricing data which is resistant to flash loan manipulation. The PRICE_BASE variable could be declared constant to save gas both on deployment and each reference. SafeMath is utilized across all contracts to prevent overflow issues.
Audit Findings Summary:
- No security issues from outside attackers were identified.
- As with any presale, ensure trust in the team prior to investing.
- Further, ensure trust in the team as they have some control in the ecosystem.
- Date: August 25th, 2021.
- Updated: September 2nd, 2021 to remove the team's ability to mint tokens at will.
Audit Results
Vulnerability Category | Notes | Result |
---|---|---|
Arbitrary Storage Write | N/A | PASS |
Arbitrary Jump | N/A | PASS |
Delegate Call to Untrusted Contract | N/A | PASS |
Dependence on Predictable Variables | N/A | PASS |
Deprecated Opcodes | N/A | PASS |
Ether Thief | N/A | PASS |
Exceptions | N/A | PASS |
External Calls | N/A | PASS |
Integer Over/Underflow | N/A | PASS |
Multiple Sends | N/A | PASS |
Suicide | N/A | PASS |
State Change External Calls | N/A | Pass |
Unchecked Retval | N/A | PASS |
User Supplied Assertion | N/A | PASS |
Critical Solidity Compiler | N/A | PASS |
Overall Contract Safety | PASS |
Details: EgoToken
($) = 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 #
+ Context
- [Int] _msgSender
- [Int] _msgData
+ 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] _beforeTokenTransfer #
+ ERC20Burnable (Context, ERC20)
- [Pub] burn #
- [Pub] burnFrom #
+ Ownable (Context)
- [Pub] #
- [Pub] owner
- [Pub] renounceOwnership #
- modifiers: onlyOwner
- [Pub] transferOwnership #
- modifiers: onlyOwner
+ EgoToken (ERC20, ERC20Burnable, Ownable)
- [Pub] #
- modifiers: ERC20
- [Pub] mint #
- modifiers: onlyOwner
Details: EgoPool
($) = 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] IBEP20
- [Ext] totalSupply
- [Ext] decimals
- [Ext] symbol
- [Ext] name
- [Ext] getOwner
- [Ext] balanceOf
- [Ext] transfer #
- [Ext] allowance
- [Ext] approve #
- [Ext] transferFrom #
+ [Int] IEgoToken (IBEP20)
+ Vault
- [Pub] #
+ BasePool (Ownable)
- [Pub] #
- [Ext] setEgoAssetRate #
- modifiers: onlyOwner
- [Ext] setDecimalAdjustment #
- modifiers: onlyOwner
- [Ext] deployRewardVault #
- [Ext] stake #
- [Pub] stakerClaim #
- [Ext] celebrityClaim #
- [Pub] calculateCelebrityEgoClaimAmount
- [Pub] calculateStakerEgoClaimAmount
- [Pub] _calculateClaimAmount
- [Pub] calculateCelebrityNetAssetReward
- [Pub] calculateCelebrityAssetClaimAmount
- [Ext] unstake #
- [Prv] _updateRate #
- [Pub] CalculatePoolRate
- [Pub] calculateAPR
- [Int] _stakeAsset #
- [Int] _celebrityClaimAsset #
- [Int] _unstakeAsset #
- [Int] _getRate
- [Ext] setPlatformFee #
- modifiers: onlyOwner
- [Ext] setPlatformFeeAddress #
- modifiers: onlyOwner
- [Ext] withrawalRewards #
- modifiers: onlyOwner
+ EgoPool (BasePool)
- [Pub] #
- modifiers: BasePool
- [Int] _stakeAsset #
- [Int] _celebrityClaimAsset #
- [Int] _unstakeAsset #
- [Int] _getRate
Details: MasterChefPool
($) = 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] IBEP20
- [Ext] totalSupply
- [Ext] decimals
- [Ext] symbol
- [Ext] name
- [Ext] getOwner
- [Ext] balanceOf
- [Ext] transfer #
- [Ext] allowance
- [Ext] approve #
- [Ext] transferFrom #
+ [Int] IEgoToken (IBEP20)
+ IMasterChef
- [Ext] enterStaking #
- [Ext] leaveStaking #
+ Vault
- [Pub] #
+ BasePool (Ownable)
- [Pub] #
- [Ext] setEgoAssetRate #
- modifiers: onlyOwner
- [Ext] setDecimalAdjustment #
- modifiers: onlyOwner
- [Ext] deployRewardVault #
- [Ext] stake #
- [Pub] stakerClaim #
- [Ext] celebrityClaim #
- [Pub] calculateCelebrityEgoClaimAmount
- [Pub] calculateStakerEgoClaimAmount
- [Pub] _calculateClaimAmount
- [Pub] calculateCelebrityNetAssetReward
- [Pub] calculateCelebrityAssetClaimAmount
- [Ext] unstake #
- [Prv] _updateRate #
- [Pub] CalculatePoolRate
- [Pub] calculateAPR
- [Int] _stakeAsset #
- [Int] _celebrityClaimAsset #
- [Int] _unstakeAsset #
- [Int] _getRate
- [Ext] setPlatformFee #
- modifiers: onlyOwner
- [Ext] setPlatformFeeAddress #
- modifiers: onlyOwner
- [Ext] withrawalRewards #
- modifiers: onlyOwner
+ MasterChefPool (BasePool)
- [Pub] #
- modifiers: BasePool
- [Int] _stakeAsset #
- [Int] _celebrityClaimAsset #
- [Prv] _prepareBalance #
- [Int] _unstakeAsset #
- [Int] _getRate
Details: VenusPool
($) = 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] IBEP20
- [Ext] totalSupply
- [Ext] decimals
- [Ext] symbol
- [Ext] name
- [Ext] getOwner
- [Ext] balanceOf
- [Ext] transfer #
- [Ext] allowance
- [Ext] approve #
- [Ext] transferFrom #
+ [Int] IComptroller
- [Ext] treasuryPercent
+ [Int] IVenusBase
- [Ext] comptroller
- [Ext] redeem #
- [Ext] redeemUnderlying #
- [Ext] balanceOf
- [Ext] exchangeRateStored
+ [Int] IVenus (IVenusBase)
- [Ext] mint #
+ [Int] IBNBVenus (IVenusBase)
- [Ext] mint ($)
+ [Int] IEgoToken (IBEP20)
+ Vault
- [Pub] #
+ BasePool (Ownable)
- [Pub] #
- [Ext] setEgoAssetRate #
- modifiers: onlyOwner
- [Ext] setDecimalAdjustment #
- modifiers: onlyOwner
- [Ext] deployRewardVault #
- [Ext] stake #
- [Pub] stakerClaim #
- [Ext] celebrityClaim #
- [Pub] calculateCelebrityEgoClaimAmount
- [Pub] calculateStakerEgoClaimAmount
- [Pub] _calculateClaimAmount
- [Pub] calculateCelebrityNetAssetReward
- [Pub] calculateCelebrityAssetClaimAmount
- [Ext] unstake #
- [Prv] _updateRate #
- [Pub] CalculatePoolRate
- [Pub] calculateAPR
- [Int] _stakeAsset #
- [Int] _celebrityClaimAsset #
- [Int] _unstakeAsset #
- [Int] _getRate
- [Ext] setPlatformFee #
- modifiers: onlyOwner
- [Ext] setPlatformFeeAddress #
- modifiers: onlyOwner
- [Ext] withrawalRewards #
- modifiers: onlyOwner
+ VenusPool (BasePool)
- [Pub] #
- modifiers: BasePool
- [Int] _stakeAsset #
- [Int] _celebrityClaimAsset #
- [Int] _unstakeAsset #
- [Int] _getRate
- [Int] _getExitRatio
Details: PancakePriceProvider
($) = payable function
# = non-constant function
Int = Internal
Ext = External
Pub = Public
+ [Int] IPriceProvider
- [Ext] getPriceBase
+ [Int] IPancakePair
- [Ext] name
- [Ext] symbol
- [Ext] decimals
- [Ext] totalSupply
- [Ext] balanceOf
- [Ext] allowance
- [Ext] approve #
- [Ext] transfer #
- [Ext] transferFrom #
- [Ext] DOMAIN_SEPARATOR
- [Ext] PERMIT_TYPEHASH
- [Ext] nonces
- [Ext] permit #
- [Ext] MINIMUM_LIQUIDITY
- [Ext] factory
- [Ext] token0
- [Ext] token1
- [Ext] getReserves
- [Ext] price0CumulativeLast
- [Ext] price1CumulativeLast
- [Ext] kLast
- [Ext] mint #
- [Ext] burn #
- [Ext] swap #
- [Ext] skim #
- [Ext] sync #
- [Ext] initialize #
+ [Int] IERC20
- [Ext] totalSupply
- [Ext] balanceOf
- [Ext] transfer #
- [Ext] allowance
- [Ext] approve #
- [Ext] transferFrom #
+ [Int] IERC20Extented (IERC20)
- [Ext] decimals
+ PancakePriceProvider (IPriceProvider)
- [Pub] #
- [Ext] getPriceBase