Platform: Code4rena
Start Date: 04/02/2022
Pot Size: $30,000 USDC
Total HM: 3
Participants: 37
Period: 3 days
Judge: leastwood
Id: 84
League: ETH
Rank: 16/37
Findings: 2
Award: $622.98
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: gellej
Also found by: Czar102, TomFrenchBlockchain, WatchPug, csanuragjain, defsec, hubble, p4st13r4, pedroais
There is no loss of funds, but there is a possibility that the current code will dictate user behavior which is not intended. Hence setting the risk rating as medium.
There is an option to setTokenOutPrice by the owner. There can be two cases. case-1. the new price is lower than the initial set price. If the price set for the sale is high, then users will wait until the end of the sale to buy in, in the expectation that there will be a price correction/lowering. This is not good for the protocol, because they will not be sure if the target sale will be achieved till the end.
case-2. the new price is more than the initial set price. If the initial price set for the sale is low, then users may buy out all the limit before the end of the sale duration. This is good for the protocol.
Contract : TokenSaleUpgradeable.sol
function setTokenOutPrice(uint256 _tokenOutPrice) external onlyOwner { require(_tokenOutPrice > 0, "TokenSale: the price must not be zero"); tokenOutPrice = _tokenOutPrice; emit TokenOutPriceUpdated(_tokenOutPrice); }
Ideally do not allow the change of tokenOutPrice during a sale duration. There will be a disparity between the early buyers and late buyers if the tokeOutPrice is changed in between sale. So, if sale target is not met, launch a new sale with lower price.
If the function of setTokenOutPrice is absolutely needed, allow only to set the new price to be greater than current one. This will influence the buying pattern. Users will try to buy early on before any price increase is possibly done. require(_tokenOutPrice > tokenOutPrice, "TokenSale: the price must be higher than current value");
#0 - GalloDaSballo
2022-02-10T02:21:22Z
The finding is valid, I think changing tokenOutPrice
kind of messes up some of the math and can also "rug" users, so we should probably make it unchangeable
#1 - 0xleastwood
2022-03-14T12:03:56Z
Duplicate of #50
107.2004 USDC - $107.20
Issue#1 : claim function should not have whenNotPaused modifier Issue#2 : finalize function should not have onlyOwner modifier
Title : claim function should not have whenNotPaused modifier
There is a possibility that the users claims can be locked (funds at risk).
If the ownerKey is compromised, then the rogue owner can pause the contract which will result in blocking the users from claiming their sale tokens.
Contract : TokenSaleUpgradeable.sol
line 192 : function claim() external whenNotPaused returns (uint256 tokenOutAmount_) {
Remove the whenNotPaused modifier in the claim() function line 192 : function claim() external returns (uint256 tokenOutAmount_) {
Title : finalize function should not have onlyOwner modifier
There is a possibility that the users claims can be locked (funds at risk).
If the ownerKey is compromised, then the rogue owner can never call the finalize() function, which will result in blocking the users from claiming their sale tokens.
If the conditions of finalize() are met, then there is no risk if this function is called by anyone.
Contract : TokenSaleUpgradeable.sol
line 254 : function finalize() external onlyOwner {
Remove the onlyOwner modifier in the finalize() function line 254 : function finalize() external {
#0 - GalloDaSballo
2022-02-14T12:52:49Z
I tend to agree