Sushi Trident contest phase 2 - tensors's results

Community-driven DeFi platform

General Information

Platform: Code4rena

Start Date: 30/09/2021

Pot Size: $100,000 SUSHI

Total HM: 24

Participants: 7

Period: 7 days

Judge: alcueca

Total Solo HM: 16

Id: 35

League: ETH

Sushi

Findings Distribution

Researcher Performance

Rank: 5/7

Findings: 3

Award: $7,508.19

🌟 Selected for report: 5

🚀 Solo Findings: 2

Findings Information

🌟 Selected for report: tensors

Labels

bug
3 (High Risk)
sponsor acknowledged

Awards

377.7706 SUSHI - $4,722.13

External Links

Handle

tensors

Vulnerability details

This is a possible line of attack on the staking contract, in particular the claimReward() function:

https://github.com/sushiswap/trident/blob/c405f3402a1ed336244053f8186742d2da5975e9/contracts/pool/concentrated/ConcentratedLiquidityPoolManager.sol#L90-L94

  1. A user with some spare capital mints a liquidity position with a very tight range (1-2 ticks wide) at the current price. Because the range is so small, his position.liquidity on his NFT is large (DyDxMath.sol).

  2. The user then sets up a bot to frontrun any price changes that someone else tries to do, burning his position after claiming rewards. He then mints a new liquidity position at the new price after the other persons trades go through.

  3. Rinse and repeat this process. If done correctly, no funds are at risk from the bot owner, he doesn't pay any fees for burning/minting either.

So what you have left is a sequence of positions with high position.liquidity and in the correct price range all the time, without taking on any risk. Thereby stealing incentive funds.

The lines below reward the bot owner with a large amount of the token: https://github.com/sushiswap/trident/blob/c405f3402a1ed336244053f8186742d2da5975e9/contracts/pool/concentrated/ConcentratedLiquidityPoolManager.sol#L90-L94

Recommendation: Lock the positions during a set time while they are staked.

#0 - sarangparikh22

2021-10-28T22:53:48Z

This seems very unlikely to happen and does not affect the pool, it's equivalent to just re balancing your position.

#1 - alcueca

2021-11-12T13:59:46Z

@sarangparikh22, Isn't the warden describing a Just In Time liquidity pattern?

#2 - sarangparikh22

2021-11-16T23:53:32Z

@alcueca yes exactly, even done right, the bot would still face huge IL. We don't intend to solve this.

Findings Information

🌟 Selected for report: tensors

Labels

bug
2 (Med Risk)
sponsor disputed

Awards

113.3312 SUSHI - $1,416.64

External Links

Handle

tensors

Vulnerability details

I'm adding this as an issue because I didn't see it mentioned anywhere in the codebase, and I think its a fair point that relates to how the protocol gives out rewards to users. As I understand , the point of staking is to provide users with additional compensation for providing liquidity (and taking on risk) for the good of the protocol. If a large fraction of rewards go to users who don't provide a huge benefit to the protocol, that's a problem.

Consider two different pools: USDC-DAI and USDC-ETH. Suppose a user has $10K worth of tokens and decides to provide liquidity to each of these pools.

In the USDC-DAI pool the user can very safely provide the $10K with a 1% spread between upper and lower tick. The total amount of liquidity he provides is roughly $10K * (1/0.01) = $1 M dollars of liquidity per second. The impermanent loss here is going to be basically 0 in normal conditions. The liquidity will be in range all the time.

The same situation in the USDC-ETH pool on the other hand: Suppose a user has $10K worth of USDC+ETH, provides it with a 1% spread between upper and lower ticks at the current price => roughly $1 M dollars of liquidity per second, the same as before. However, now there is a good chance that price ranges by more than 1% meaning he loses all of his more valuable tokens for the cheaper ones due to impermanent loss. The liquidity will be out of range for a much longer percentage of the time.

However, if the incentives for each pool are the same, the staking protocol would value the liquidity per second of each LP situation equally. To make things "fair per unit of risk/liquidity" the incentive on the USDC-ETH should be something like 10x or 20x the incentive on the USDC-DAI pool. The pools with higher volatility should have a significantly higher incentive.

Recommendations: Make sure the developers are at least aware of something like this when choosing incentive amounts for different pools. Carefully choose incentive amounts for each pool.

#0 - sarangparikh22

2021-10-12T10:12:38Z

This is not a med-risk issue, or an issue at all, we will improve the docs, so that devs are aware on how to set the incentives.

#1 - alcueca

2021-11-12T13:55:25Z

Setting the incentives wrong will make the protocol leak value, which warrants a Severity 2. The issue was not disclosed, and therefore is valid.

Findings Information

🌟 Selected for report: 0xsanson

Also found by: tensors

Labels

bug
duplicate
1 (Low Risk)
sponsor acknowledged

Awards

16.9997 SUSHI - $212.50

External Links

Handle

tensors

Vulnerability details

It is possible that a typo results in an incentive having no owner, meaning it cannot be recalled by the reclaimIncentive function:

https://github.com/sushiswap/trident/blob/c405f3402a1ed336244053f8186742d2da5975e9/contracts/pool/concentrated/ConcentratedLiquidityPoolManager.sol#L57

addIncentive() should have a standard check to make sure that an owner is declared so that funds aren't lost.

#0 - alcueca

2021-11-12T10:49:56Z

Choosing #76 as the main.

Findings Information

🌟 Selected for report: tensors

Also found by: broccoli

Labels

bug
1 (Low Risk)
sponsor disputed

Awards

16.9997 SUSHI - $212.50

External Links

Handle

tensors

Vulnerability details

It is widely considered best practice to lock the pragma statements to a specific compiler. See, for example, https://swcregistry.io/docs/SWC-103

Contracts should be deployed with the same compiler version and flags that they have been tested with thoroughly. Locking the pragma helps to ensure that contracts do not accidentally get deployed using, for example, an outdated compiler version that might introduce bugs that affect the contract system negatively.

https://github.com/sushiswap/trident/blob/c405f3402a1ed336244053f8186742d2da5975e9/contracts/pool/concentrated/ConcentratedLiquidityPool.sol#L3

#0 - sarangparikh22

2021-10-11T13:05:02Z

The compiler version to use is fixed in hardhat settings.

#1 - alcueca

2021-11-12T10:53:17Z

Severity 1 is correct.

Findings Information

🌟 Selected for report: tensors

Labels

bug
1 (Low Risk)
sponsor acknowledged

Awards

37.7771 SUSHI - $472.21

External Links

Handle

tensors

Vulnerability details

Consider using version 0.8.8 instead of using solidity 0.8.0. More recent versions of solidity have compiler optimizations, user defined types (this would be very useful in the concentratedLiquidityPools code), overriding interface functions, reading from immutables, among other things. This could help reading and writing safe and clean code.

https://github.com/sushiswap/trident/blob/c405f3402a1ed336244053f8186742d2da5975e9/contracts/pool/concentrated/ConcentratedLiquidityPool.sol#L3

#0 - sarangparikh22

2021-10-11T15:13:41Z

This is non critical issue.

Findings Information

🌟 Selected for report: tensors

Labels

bug
1 (Low Risk)
sponsor disputed

Awards

37.7771 SUSHI - $472.21

External Links

Handle

tensors

Vulnerability details

The functions on L274, L439, L667 is not used. I guess, other Pool contracts in Trident use them, but since they just revert here, there is no point in including them. Unused code can hint at programming or architectural errors.

Recommended Mitigation Steps Use it or remove it.

Example: https://github.com/sushiswap/trident/blob/c405f3402a1ed336244053f8186742d2da5975e9/contracts/pool/concentrated/ConcentratedLiquidityPool.sol#L274

#0 - sarangparikh22

2021-10-13T20:27:15Z

These functions are present to conform the IPool standard of the Trident, if we remove them, the compilation would fail.

#1 - alcueca

2021-11-12T14:02:57Z

You are not really conforming to the standard if necessary functions revert. While this is not an issue in the ConcentratedLiquidityPool itself, it points to an issue with your IPool standard, or with the applicability of the IPool standard to the ConcentratedLiquidityPool.

Platforms that expect contracts to conform with IPool now have to deal with the fact that some IPool contracts behave differently. Sustained.

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