Platform: Code4rena
Start Date: 25/01/2022
Pot Size: $50,000 USDT
Total HM: 17
Participants: 39
Period: 3 days
Judge: LSDan
Total Solo HM: 9
Id: 79
League: ETH
Rank: 16/39
Findings: 2
Award: $984.37
🌟 Selected for report: 1
🚀 Solo Findings: 0
🌟 Selected for report: harleythedog
Also found by: sirhashalot
700.6157 USDT - $700.62
harleythedog
In LaunchEvent.sol
, the function _safeTransferAVAX
is as follows:
function _safeTransferAVAX(address _to, uint256 _value) internal { (bool success, ) = _to.call{value: _value}(new bytes(0)); require(success, "LaunchEvent: avax transfer failed"); }
This function is utilized in a few different places in the contract. According to the Solidity docs), "The low-level functions call
, delegatecall
and staticcall
return true
as their first return value if the account called is non-existent, as part of the design of the EVM. Account existence must be checked prior to calling if needed".
As a result, it is possible that this call will fail, but _safeTransferAVAX
will not notice anything went wrong. In particular, it is possible that the address rocketJoeFactory.penaltyCollector()
is a deleted contract (perhaps a security flaw was found and selfdestruct
was called so that users know to use an updated smart contract), but _safeTransferAVAX
will not revert. If rocketJoeFactory.penaltyCollector()
is indeed a non-existent contract, it would be better for _safeTransferAVAX
to revert until an admin can manually correct the penaltyCollector
in the factory.
For reference, see a similar high severity reported in a Uniswap audit here (report # 9): https://github.com/Uniswap/v3-core/blob/main/audits/tob/audit.pdf
See _safeTransferAVAX
here. See how this function is called with _to
as rocketJoeFactory.penaltyCollector()
here, but this contract's existence is not verified, which is a problem as described above.
Inspection.
Check for contract existence on low-level calls, so that failures are not missed.
🌟 Selected for report: cmichel
Also found by: UncleGrandpa925, WatchPug, harleythedog
harleythedog
The whole point of the LaunchEvent.sol
contract is to gather token
and WAVAX
to be added to a JoePair. Looking at the JoeRouter02.sol
code here, I am not seeing anything preventing a griefer from creating a pair for token
and WAVAX
before the LaunchEvent.sol
function createPair
can be called. If a griefer does this, and adds a tiny bit of liquidity, there is essentially no cost to the griefer, and all calls to createPair
will revert due to the require statement here.
This jeopardizes the whole point of the contract, and the griefing attack would be easy to time (since LaunchEvent.sol
has to complete 3 stages before createPair
can even be called), so I consider this a high severity issue.
See the code for createPair
here.
Inspection.
The require statements in createPair
should be reconsidered. Requiring that there be zero supply if the pair already exists is too restrictive. Perhaps only a certain amount of liquidity should be allowed, but certainly more than zero should be allowed, or else anyone can easily grief as described above.
#0 - cryptofish7
2022-01-31T14:19:48Z
Duplicate of #246
#1 - dmvt
2022-02-22T19:49:32Z
Duplicate of #197. Funds would not be lost but protocol availability would be impacted.