Skip to content

Instantly share code, notes, and snippets.

@RideSolo
Last active December 16, 2020 01:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RideSolo/0ab28f3be1d981114d5727cafd6c7afc to your computer and use it in GitHub Desktop.
Save RideSolo/0ab28f3be1d981114d5727cafd6c7afc to your computer and use it in GitHub Desktop.

SushiSwap Security Review Report.

1. Summary

This document is a security audit report where sushiswap-settlement and bentobox have been reviewed.

2. In scope (format: md5sum => contract name)

2.1. sushiswap-settlement (github commit: a5472ee)

  • 7d80bae4926d212c3ffad050610cf19d ./OrderBook.sol
  • 46cee707e6bb462f4affcfebe247fe9f ./Settlement.sol
  • 14cb8ab1973dc2b1809f9c27909d4d8b ./UniswapV2Router02Settlement.sol
  • 2d4ded3e2ab0d01d187a9457abefef8 ./interfaces/IMasterChef.sol
  • 73382b325285432af6e89bef11dec9d5 ./interfaces/IMintable.sol
  • 70ec2cf3a5ae0eb6cec673c4beb61cf5 ./interfaces/ISettlement.sol
  • ba01b1c6046aab91923c57ccd3a15ef6 ./libraries/Bytes32Pagination.sol
  • d0224a1a326b6cb83702c9c24c3d74c4 ./libraries/Orders.sol
  • 2fcf13fc9f81c6ae97a1fe582c00f357 ./libraries/Verifier.sol
  • 4763386b7f688e4963736e8e1580cc69 ./mixins/Ownable.sol

2.2. bentobox (github commit: c0161d9)

  • bd2bdf9072e87301fd48881ea9bea180 ./ERC20.sol
  • 7165e1bbc042e1bed9b8b10889ca339f ./libraries/BoringMath.sol
  • 952bec4328cd74f10daea92087342bf7 ./libraries/Ownable.sol
  • 1983e0e0a4e4175118835ffcfed40ca6 ./oracles/ChainLinkOracle.sol
  • 1455dbd2c1a835d2d30a525592bb25f8 ./oracles/CompositeOracle.sol
  • 89e038aebbced99e560822a942e0e5ed ./oracles/CompoundOracle.sol
  • b900859dd29ca70501bc49e990e87795 ./oracles/PeggedOracle.sol
  • 7f68aee95853cd72ec52cf2dcc4a4dd8 ./oracles/SimpleSLPTWAP0Oracle.sol

2.3. Partially Verified

  • 46b16592b7b561f61eafc3e74fe68220 ./BentoBox.sol
  • cc8cfb53de3bd72365b53a6df6d35367 ./LendingPair.sol
  • 69752817dbf62f3c2707936b02d2c400 ./swappers/SushiSwapSwapper.sol

3. Findings

3.1. Unsecure Offline Order Signature

Severity: medium

File(s)

  • ./sushiswap-settlement/contracts/OrderBook.sol
  • ./sushiswap-settlement/contracts/Settlement.sol

Description

Offline signed orders submitted through OrderBook.createOrder or fillOrder._validateArgs do not implement EIP712. Without the correct usage of EIP712 the users will be prompted to sign a non-readable hexadecimal strings.

Such implementation represent a security risk:

  • Users will need to sign unreadeable hexadecimal strings, which is confusing and insecure.
  • Wallets that implement EIP712 such as Metamask combined with a correct EIP712 implementaion onchain, will also prevents signatures meant for one network, to work on another one. This feature will be enabled only if the chainId is used as a field EIP712 domain separator.

Fore more details refer:

Recommendation

EIP712 must be implemented to avoid the issues described above.

3.2. High Gas Usage

Severity: High

File(s)

  • ./sushiswap-settlement/contracts/OrderBook.sol

Description

OrderBook._addHash uses a loop to iterate over all the array of hashes to check the deadline. Knowing that OrderBook._addHash is used to append newly created order hash in OrdeoBook.createOrder into four different arrays, the gas consumption will increase depending on the array size untill reaching block gas limit. In the same function, moving all the array elmenents starting from the fetched index will also make the gas consumption extremly higher since it SLOAD SSTORE will be extensively used.

Recommendation

The actual sorting algorithm must be optimized or completely refactored.

3.3. Unexecuted Orders Due to Allowance

Severity: medium

File(s)

  • ./sushiswap-settlement/contracts/Settlement.sol

Description

If an order maker decrease the allowace previously approved to the settlement contract the internal call to Settlement._swapExactTokensForTokens will throw. However, batch execution will also throw in this case, this behavior is not wanted by the calling addresses since it can cause them losses and delay when executing users orders that can lead to unexecuted orders if the price movement is too quick.

Recommendation

when executing multiple orders the allowance must be checked and the function must return amountOut equal to zero before transfering the tokens to the pair contract since the transaction will throw.

3.4. Unlocked Pragma

Severity: Informational

File(s)

  • ./sushiswap-settlement/contracts/mixins/ownable.sol

Description

Every Solidity file specifies in the header a version number of the format pragma solidity (^)0.*.*. The caret (^) before the version number implies an unlocked pragma, meaning that the compiler will use the specified version and above, hence the term "unlocked".

Recommendation

For consistency and to prevent unexpected behavior in the future, it is recommended to remove the caret to lock the file onto a specific Solidity version.

3.5. Clone and Own

Severity: informational

File(s)

  • ./sushiswap-settlement/contracts/mixins/ownable.sol

Description

The clone-and-own approach involves copying and adjusting open source code at one's own discretion. From the development perspective, it is initially beneficial as it reduces the amount of effort. However, from the security perspective, it involves some risks as the code may not follow the best practices, may contain a security vulnerability, or may include intentionally or unintentionally modified upstream libraries.

Recommendation

Rather than the clone-and-own approach, a good industry practice is to use the Truffle framework for managing library dependencies. This eliminates the clone-and-own risks yet allows for following best practices, such as, using libraries.

3.6. Non-Compliance to ERC20 Standard

Severity: medium

File(s)

  • ./bentobox/contracts/ERC20.sol

Description

Following EIP-20, ERC20 functions transfer and transferFrom must allow zero value transfers and should throw in case if the users has insufficient balance or allowance. The implemented ERC20 contract does not comply with the description stated above.

Recommendation

Follow the ERC20 specifications to implement a fully compatible ERC20 token.

3.7. Signature Malleability for Ecrecover

Severity: medium/high

Description

Externaly signed order are not protected against signature malleability. No unique value (such as nonce for each user) is saved on chain to guarentee the uniqueness of the signature.

For more details refer to https://swcregistry.io/docs/SWC-117.

File(s)

  • ./sushiswap-settlement/contracts/OrderBook.sol
  • ./sushiswap-settlement/contracts/Settlement.sol

Recommendation

V, R, S signature inputs are not validated, all values should be verified as recommended here.

3.8. Enable To Verfiy Hardcoded TYPE_HASH

Severity: Low/BP

File(s)

  • ./bentobox/contracts/ERC20.sol

Description

The hardcoded TYPE_HASH value used in ERC20.permit function cannot be verified.

Recommendation

Either calculate the TYPE_HASH on chain or include the hashed string in the code as a comment.

3.9. ChainLink Oracle May Return Stale Price

Severity: medium

File(s)

  • ./bentobox/oracles/ChainLinkOracle.sol

Description

The return value from IAggregator.latestRoundData is not checked if stale, please note that the returned values in get and peek are hardcoded to be true. ChainLink oracle relies on third paties to update the aggregator average price.

Recommendation

If the project team cannot guarentee that the aggragator is updated, the value returned by get and peek must return false when the aggregator price is stale.

3.10. Possible Incorrect Aggregators Average Price Decimals

Severity: low

File(s)

  • ./bentobox/oracles/ChainLinkOracle.sol

Description

_get function uses a decimals value passed throught function arguments, the decimals value might be incorrect since every Chainlink aggregator uses it own decimals value.

Recommendation

Chainlink aggregator implement a function that returns the decimals value of the returned average price, the value should be used to compute the final price in _get function.

3.11. Un-updated Exchange Rate

Severity: High

File(s):

  • ./bentobox/contracts/LendingPair.sol

Description

Exchange rate is not updated when isSolvent is callad, under colateralized users might be able to borrow asset even if they should not in case of a correct exchange rate.

Recommendation

Exchange rate should be updated prior to such actions.

3.12. Incorrect ETH/WETH Deposit/Withdrawal Logic

Severity: low

File(s):

  • ./bentobox/contracts/BentoBox.sol

Description

If a user owns WETH in his EOA he won't be able to deposit it since the BentoBox.deposit function handle WETH as if it was ETH, meaning that the WETH.deposit external call will fail. Simialrly a user who wants to withdraw WETH will get ETH instead. The last one can be problematic for contract that does not handle such situaltion.

Recommendation

A dummy ETH address can be used to handle ETH deposit and withdrawal that is not equal to the WETH token address.

3.13. Fund Deposited Directly Can be Taken by Any Address

Severity: low

File(s):

  • ./bentobox/contracts/BentoBox.sol

Description

skim/skimTo allow anyone to take tokens deposited through transfer function directly.

Recommendation

Use access restriction to allow only required contracts and administrators to call skim/skimTo

3.14. Alway True Condiction in Compound Oracle

Severity: low

File(s):

  • ./bentobox/oracles/CompoundOracle.sol

Description

In _getPrice and _peekPrice blocknumber + 8 is always higher than info.blocknumber. This will lead to price to be updated at every call.

Recommendation

Set info.blocknumber to block.number + 8, and change the condition to if (block.number > info.blockNumber).

3.15. Possible Decimals Error in Compound Oracle

Severity: undetermined

File(s):

  • ./bentobox/oracles/CompoundOracle.sol

Description

It is undertermined if the Compound anchor returned price decimals fixed. However, in peek and get functions 1e36 is used as base.

Recommendation

Decimals should be get dynamicaly from their related contracts or tokens to be sure that no conversion errors happen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment