Trader Joe contest - sirhashalot's results

One-stop-shop decentralized trading on Avalanche.

General Information

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

Trader Joe

Findings Distribution

Researcher Performance

Rank: 5/39

Findings: 5

Award: $2,357.40

🌟 Selected for report: 3

πŸš€ Solo Findings: 1

Findings Information

🌟 Selected for report: harleythedog

Also found by: sirhashalot

Labels

bug
duplicate
2 (Med Risk)

Awards

700.6157 USDT - $700.62

External Links

Handle

sirhashalot

Vulnerability details

Impact

The RocketJoeStaking.sol _safeRJoeTransfer() function doesn't use the OpenZeppelin SafeERC20 safeTransfer() function. Instead, it uses the standard transfer() function and applies logic to avoid withdrawing more rJoe than is available. Using a function name with the word "safe" when the function does not check the return values of function calls is misleading and can lead to security issues with later misuse. Because safeTransfer() is used elsewhere in this contract for the joe token, so most likely this is an oversight and safeTransfer() for the rJoe token was intended.

Proof of Concept

The _safeRJoeTransfer function in RocketJoeStaking.sol does not check the function return value and therefore does not deserve the name safe. Compare the _safeRJoeTransfer() function to the _safeTransferAVAX() function in LaunchEvent.sol, which does check the return value.

If a function's name includes with word "safe", it should check the function return value. Use safeTransfer() in the _safeRJoeTransfer() function. If safeTransfer is not needed, rename the function to rJoeTransferIfAvailable or similar.

#0 - cryptofish7

2022-01-31T14:51:58Z

Duplicate of #170

Findings Information

🌟 Selected for report: sirhashalot

Labels

bug
2 (Med Risk)
sponsor acknowledged

Awards

1556.9237 USDT - $1,556.92

External Links

Handle

sirhashalot

Vulnerability details

Impact

The LaunchEvent.sol createPair() function calls router.addLiquidity() with a amountADesired == amountAMin and amountBDesired == amountBMin. Because there is no allowance for slippage, if the zero slippage requirement is not met then the addLiquidity() function will revert and prevent users from using the createPair() function. This could be caused either by frontrunning the createPair call or in a situation where the liquidity pool exists but does not allow for zero slippage with the assets it is holding.

Proof of Concept

The zero slippage addLiquidity call is found in LaunchEvent.sol. This code may have been written with the assumption that only Rocket Joe will have a balance of the new token, so no other user could call the addLiquidity function with both assets, since the whitepaper states "Rocket Joe liquidity launch will complete before launchpad public sale release any tokens to the public". However, the new token contract should be considered untrusted and Rocket Joe cannot guarantee where all the new tokens are before phase 3 of the Rocket Joe launch event, which is when createPair() is called. The token creator who has control over the token allocation is not controlled by Trader Joe, so an attacker who has early access to the new token can break the outlined assumptions.

Consider how the launch event functions may break if the new token is launched by an attacker who doesn't follow the assumptions outlined. One solution for this createPair() issue is to add an input parameter to the function to handle a slippage allowance.

Findings Information

Labels

bug
duplicate
2 (Med Risk)

Awards

60.3184 USDT - $60.32

External Links

Handle

sirhashalot

Vulnerability details

Impact

The LaunchEvent.sol contract handles arbitrary ERC20 tokens for launch events. These ERC20 tokens may have unexpected behavior such as unexpected return values (like these 130 tokens). By using the standard ERC20 functions and not checking the return values of these functions, a malicious token could be created to exploit the launch event code. Observe that safeTransfer() is used for the JOE token in RocketJoeStaking.sol but this is not consistent across all contracts.

Proof of Concept

This issue is most prominent in LaunchEvent.sol, with several ERC20 transfer() calls like this one on line 458.

Use OpenZeppelin safeTransfer() functions to improve edge case handling by checking the return value of the transfer() function.

#0 - cryptofish7

2022-01-31T14:46:52Z

Duplicate of #12

#1 - dmvt

2022-02-22T10:51:25Z

This could result in a loss of funds given the right external conditions.

2 β€” Med (M): vulns have a risk of 2 and are considered β€œMedium” severity when assets are not at direct risk, but the function of the protocol or its availability could be impacted, or leak value with a hypothetical attack path with stated assumptions, but external requirements.

Findings Information

🌟 Selected for report: sirhashalot

Also found by: 0v3rf10w, 0x1f8b, Dravee, UncleGrandpa925, cccz, defsec, gzeon

Labels

bug
1 (Low Risk)
sponsor confirmed

Awards

31.028 USDT - $31.03

External Links

Handle

sirhashalot

Vulnerability details

Impact

Some functions in RocketJoeFactory.sol have zero checks for setting specific state variables, but there zero address checks are not always applied. Setting some of these state variables to the zero address, whether intentional or not, can break the protocol functionality. Adding these checks consistently would prevent this scenario.

Proof of Concept

The constructor in RocketJoeFactory.sol performs zero address checks before setting the router, factory, penaltyCollector, and rJoe state variables. Later in the same contract, the functions setRJoe(), setPenaltyCollector(), setRouter(), and setFactory() omit the same zero address checks that were applied earlier. Since the issues that can be caused by setting these state variables to the zero address exist whether setting the value in the constructor or in the setter function, these checks should be applied consistently.

Add zero address checks in the setter functions for these state variables just like is done in the constructor. If it is determined that a zero check for any of these state variables is not needed, then the zero check can be removed from the RocketJoeFactory.sol constructor for consistency.

#0 - cryptofish7

2022-01-31T22:23:39Z

Findings Information

🌟 Selected for report: WatchPug

Also found by: Czar102, Dravee, Jujic, Meta0xNull, byterocket, defsec, p4st13r4, pauliax, robee, sirhashalot

Labels

bug
duplicate
G (Gas Optimization)

Awards

1.2609 USDT - $1.26

External Links

Handle

sirhashalot

Vulnerability details

Impact

Strings are broken into 32 byte chunks for operations. Revert error strings over 32 bytes therefore consume extra gas as documented publicly

Proof of Concept

There are multiple examples of this gas optimization opportunity, including but not limited to:

Reducing revert error strings to under 32 bytes decreases deployment time gas and runtime gas when the revert condition is met. Alternatively, the code could be modified to use custom errors, introduced in Solidity 0.8.4: https://blog.soliditylang.org/2021/04/21/custom-errors/

#0 - cryptofish7

2022-02-11T01:08:19Z

Duplicate of #242

Findings Information

🌟 Selected for report: sirhashalot

Also found by: Dravee, Rhynorater, robee

Labels

bug
G (Gas Optimization)
sponsor confirmed

Awards

7.2498 USDT - $7.25

External Links

Handle

sirhashalot

Vulnerability details

Impact

The withdrawAVAX() function of LaunchEvent.sol and initialize() function of RocketJoeStaking.sol can be declared external for gas savings

Proof of Concept

Declare functions as external instead of public when possible

#0 - cryptofish7

2022-01-31T19:38:53Z

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax Β© 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter