Slingshot Finance contest - kenzo's results

Web3 trading platform.

General Information

Platform: Code4rena

Start Date: 30/10/2021

Pot Size: $35,000 ETH

Total HM: 2

Participants: 16

Period: 3 days

Judge: alcueca

Total Solo HM: 1

Id: 48

League: ETH

Slingshot Finance

Findings Distribution

Researcher Performance

Rank: 1/16

Findings: 4

Award: $10,594.91

🌟 Selected for report: 4

πŸš€ Solo Findings: 1

Findings Information

🌟 Selected for report: WatchPug

Also found by: daejunpark, gpersoon, hickuphh3, kenzo, pmerkleplant

Labels

bug
duplicate
2 (Med Risk)
disagree with severity

Awards

588.8441 USDC - $588.84

External Links

Handle

kenzo

Vulnerability details

When toToken == nativeToken, executeTrades compares Executioner's starting nativeToken balance to Executioner's ending wrappedNativeToken balance.

Impact

  • Loss of user funds or DOS of executeTrades: if there is extra ETH in Executioner contract, finalOutputAmount will be calculated to be smaller than it really is, thereby sending less tokens than deserved to the user, or failing the >= finalAmountMin check and erroneously failing the trade.
  • Skimming of accidently-sent WETH: if Executioner's WETH balance is > 0, a user can craft a trade that will send these tokens to him.

Proof of Concept

Slingshot saves the initialBalance as: uint256 initialBalance = _getTokenBalance(toToken); https://github.com/code-423n4/2021-10-slingshot/blob/main/contracts/Slingshot.sol#L81 If toToken == nativeToken, initialBalance will be Executioner's nativeToken (ETH) balance. https://github.com/code-423n4/2021-10-slingshot/blob/main/contracts/Slingshot.sol#L158:#L159

Then after the trades, if toToken == nativeToken, Slingshot sends wrappedNativeToken to _getTokenBalance. https://github.com/code-423n4/2021-10-slingshot/blob/main/contracts/Slingshot.sol#L87:#L88 Therefore, finalBalance will be Executioner's wrappedNativeToken balance (WETH), unlike initialBalance (ETH). This inconsistency manifests the two scenarios mentioned in Impact above. Loss of user funds or DOS of executeTrades - if there is extra ETH in Executioner, uint finalOutputAmount = finalBalance - initialBalance gives a wrong result and might send user less tokens than deserved or fail the finalOutputAmount >= finalAmountMin check. https://github.com/code-423n4/2021-10-slingshot/blob/main/contracts/Slingshot.sol#L92 Skimming of accidently-sent WETH: If a user sends a trade where toToken == nativeToken, he will transfer to himself all the extra wrappedNativeToken in Executioner as initialBalance is the Executioner's nativeToken balance, not wrappedNativeToken.

Tools Used

Manual analysis

In initialBalance, instead of passing toToken to _getTokenBalance: https://github.com/code-423n4/2021-10-slingshot/blob/main/contracts/Slingshot.sol#L81 Align it with the same mechanism that is used to check finalBalance: https://github.com/code-423n4/2021-10-slingshot/blob/main/contracts/Slingshot.sol#L87:#L91

#0 - tommyz7

2021-11-03T14:40:49Z

Duplicate of #18, medium risk since no user funds are at risk because of finalAmountMin will guard it.

Findings Information

🌟 Selected for report: kenzo

Labels

bug
2 (Med Risk)
disagree with severity

Awards

5983.2756 USDC - $5,983.28

External Links

Handle

kenzo

Vulnerability details

Slingshot's executeTrades checks that the trade result amount (to be sent to the user) is bigger than finalAmountMin, and after that sends the user the amount. But if the token charges fee on transfer, the final transfer to the user will decrease the amount the user is getting, maybe below finalAmountMin.

Proof of Concept

Slingshot requires finalOutputAmount >= finalAmountMin before sending the funds to the user: https://github.com/code-423n4/2021-10-slingshot/blob/main/contracts/Slingshot.sol#L93:#L98 So if the token charges fees on transfer, the user will get less tokens than finalOutputAmount . The check of finalOutputAmount against finalAmountMin is premature.

Tools Used

Manual analysis

Save the user's (not Executioner's) toToken balance in the beginning of executeTrades after _transferFromOrWrap(fromToken, _msgSender(), fromAmount), and also in the very end, after executioner.sendFunds(toToken, _msgSender(), finalOutputAmount) has been called. The subtraction of user's initial balance from ending balance should be bigger than finalAmountMin. https://github.com/code-423n4/2021-10-slingshot/blob/main/contracts/Slingshot.sol#L65:#L99

#0 - tommyz7

2021-11-03T15:10:32Z

Slingshot concern is to execute the trade as promised and make sure we are sending to the user what has been promised in trade estimation. If the token adds additional taxation on transfer, it is on the user side and users understand and accept this. We have seen this play out on production for the previous version of the contracts and we decided not to make that check. It seems the most practical decision.

Personally, I think this is non-critical.

#1 - alcueca

2021-11-06T05:56:52Z

The severity for the issue is right. The sponsor should add documentation to the fact that some tokens might not conform to common expectations.

Findings Information

🌟 Selected for report: kenzo

Labels

bug
1 (Low Risk)
disagree with severity

Awards

1994.4252 USDC - $1,994.43

External Links

Handle

kenzo

Vulnerability details

IUniswapModule has a comment: for now, we only supporting .swapExactTokensForTokens() However, the actual function being called is swapExactTokensForTokensSupportingFeeOnTransferTokens. It is unclear whether the comment makes the distinction between "swapETH" and "swapTokens" functions or "swapExactTokensForTokens" and "swapExactTokensForTokensSupportingFeeOnTransferTokens" functions.

It is unclear whether the usage of swapExactTokensForTokensSupportingFeeOnTransferTokens was properly tested as the comment mentions another literal function name. I suggest clarifying the comment.

#0 - tommyz7

2021-11-04T17:15:02Z

Outdated comment, however I don't see where's a risk here. In my opinion it's non-critical.

#1 - alcueca

2021-11-06T05:52:41Z

Issues with comments are severity 1

Findings Information

🌟 Selected for report: kenzo

Labels

bug
1 (Low Risk)
disagree with severity

Awards

1994.4252 USDC - $1,994.43

External Links

Handle

kenzo

Vulnerability details

There's a comment in CurveModule: the only unique logic in this contract calculates post-trade balance because Curve's innovative design choice of not returning an output amount. https://github.com/code-423n4/2021-10-slingshot/blob/main/contracts/module/CurveModule.sol#L26:#L27 However, there seems to be no such calculation in the module. https://github.com/code-423n4/2021-10-slingshot/blob/main/contracts/module/CurveModule.sol#L57:#L59

It is unclear whether the check should be there, what it's purpose is, and if something is wrong as the check is missing. I suggest clarifying the comment.

#0 - tommyz7

2021-11-04T17:14:38Z

Outdated comment, however I don't see where's a risk here. In my opinion it's non-critical.

#1 - alcueca

2021-11-06T05:52:08Z

Issues with comments and classified as severity 1.

Findings Information

🌟 Selected for report: kenzo

Also found by: pauliax

Labels

bug
G (Gas Optimization)

Awards

33.9293 USDC - $33.93

External Links

Handle

kenzo

Vulnerability details

ConcatStrings prependNumber is not used in the project.

Impact

Unnecessary gas spent on deployment.

Proof of Concept

https://github.com/code-423n4/2021-10-slingshot/blob/main/contracts/lib/ConcatStrings.sol#L31

Tools Used

Manual analysis, search in files

Remove function from library.

#0 - tommyz7

2021-11-04T18:20:36Z

Duplicate of #100

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