Sherlock

QuantstampFiles named in the report

Quantstamp reviewed Sherlock on 10 Aug 2021: 25 findings, 0 critical; 6 marked fixed, 16 acknowledged, 3 open.

No open critical findings
Open the reportOpen Sherlock’s security record

Report hosted on certificate.quantstamp.com.

Trustblock does not review code.

Findings25

Statuses are the security firm’s own, from its report.

SeverityOpenAcknowledgedFixed
Critical000
High001
Medium041
Low3124
MediumAdding/Updating Protocols Should Be TimelockedAcknowledged

Staker funds are used as support for all protocols supported by Sherlock. Therefore, adding a new protocol may introduce a risk that one or more *stakers* are not comfortable with. For example, a *staker* might know the team behind a certain protocol that is newly added and believe that the risk of a hack of that protocol is too high to tolerate. Therefore, *stakers* should get a chance to withdraw their funds before a protocol starts being covered by Sherlock.

MediumFirst Money Out Pool Not Emptied FirstAcknowledged

When calling the `Payout.payout` function the governance address can choose the amount that is to be transferred from the `firstMoneyOut` pool for each token. This goes against the specification, which indicates that the `firstMoneyOut` pool will be emptied first in case of a valid claim.

MediumInsufficient Buffer For Price FluctuationsAcknowledged

The documentation states that: > Sherlock implements a buffer amount (20% currently) to account for currency fluctuations. So if Sherlock will cover a protocol for $100M, the staking pools need to be at least $120M in size ($100M we need to cover + 20% buffer). However, given that we have seen price drops of more than 50% in the past couple of months, this 20% buffer seems insufficient.

MediumProtocol May Overpay Premium FeeAcknowledged

The Sherlock pool must hold at least the amount necessary to payout the largest protocol, plus a 20% buffer. However, if a large *staker* decides to withdraw their stake at some point and the size of the pool decreases below the amount needed by one or more of the largest platforms, then those platforms will overpay the amount of premium from that point onward until either the premium amount is adjusted by the governance or sufficient funds are staked to restore the pool size to the amount needed to cover the largest platforms.

LowAllowance Double-Spend ExploitAcknowledged

As it presently is constructed, the contract is vulnerable to the [allowance double-spend exploit](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/b4f87bb8fc25fb07f73099701e39e167a3d36465/contracts/token/ERC20/ERC20.sol#L71-L78), as with other ERC20 tokens.

LowCooldown Period Could Be Excessively LongAcknowledged

The governance can set the cooldown period to 25 million blocks, which (assuming a block time of 13 seconds) is over 10 years. This is an excessive amount of time for stakers to wait before they can withdraw their funds.

LowImportant Contract Operations Cannot Be Easily MonitoredAcknowledged

The contract does not declare any events, which makes it difficult for 3rd party integrators to monitor the actions performed by the smart contracts. The only exception is the `SherX.sol` file that defines and emits the `Harvest` event.

LowMissing Input ValidationAcknowledged

The following functions are missing input parameter validation: 1. The `GovDev.transferGovDev()` function does not check if the `_govDev` parameter is different from `address(0)`. 2. The `Payment.payment()` method does not check if the same token address is provided twice in the `_tokens` input array parameter. 3. The `_amounts` and `_firstMoneyOut` values are not checked to be less than the available amounts in the pools. There is an implicit check by using SafeMath functions which will fail if these conditions are false, but will not provide a proper error message. 4. The `_amount` input parameter of the `PoolBase.withdrawProtocolBalance` function is not explicitly checked to be less than `ps.protocolBalance[_protocol]`. This could lead to an error in the `sub()` function call on L292, without any error message. 5. The `PoolBase.setCooldownFee` function does not impose an upper limit on the `_fee` parameter value and this fee can be changed at any time by the governance account.

LowPrivileged RolesAcknowledged

1. From the protocol overview: "Our claims committee will be the final arbiters in deciding whether a certain hack falls under coverage and therefore should be paid out." 2. Within `Gov.sol`, several protocol parameters may be changed, e.g., `unstakeWindow`. 3. The owner is responsible for setting token prices and protocol premiums. **No oracles are used for pricing.** 4. The diamond pattern would allow the owner to add arbitrary code to the solution as facets via `GovDev.updateSolution`. Also, other privileged roles should be documented, which can perform a series of actions that could affect end-users: * The main governance role can do the following: 1. Change the address of the main governance role at any time. 2. Change the Watson's address at any time. 3. Set the length of the unstake window to any value under 10 years, at any time. 4. Set the length of the cooldown period to any value under 10 years, at any time. 5. Add new protocols at any time. 6. Update the protocol agent at any time. 7. Add any ERC20 tokens the protocol is allowed to pay in at any time. 8. Remove protocols that do not have debt. 9. Initialize a new token. 10. Disable any of the added ERC20 tokens with 0 active weight, for staking. 11. Disable any covered protocol if the active premium and active underlying are 0. 12. Sell/swap ERC20 tokens from the pool at any time. 13. Remove ERC20 tokens from the pool if they are not used by stakers or protocols. 14. Set the price of any ERC20 token in USD at any time. 15. Set the premium amounts for a protocol using multiple ERC20 tokens. 16. Change the address of the payout governance, at any time. 17. Set initial SHERX distribution to Watsons, once. 18. Set the SHERX distribution (weights) to different ERC20 tokens at any time. * The GovDev role can do the following: 19. Set the initial main governance address, once. 20. Change the GovDev address, at any time. 21. Delete, update or add functions to the Sherlock smart contract. 22. Set the initial governance payout address, once. 23. Initialize the SherXERC20 token, once. 24. Stake in the `PoolDevOnly` contract. No other role can stake in this pool.

LowProtocol Premium Change IssueAcknowledged

The `Manager.setProtocolPremium` and `Manager.setProtocolPremiumAndTokenPrice` functions are used to change the premium amount for one or more protocols. These functions all make a call to `LibPool.payOffDebtAll` which pays off the accrued debt of all whitelisted protocols that use a specific token. However, if any of these protocols do not have sufficient balance for the debt to be paid off, it will cause the whole transaction to revert and the protocol premium price will remain unchanged (for any unrelated protocol).

Show 6 more
LowStakeholder Incentives Are Not Fully AlignedAcknowledged

There is a conflict of interest between the protocols and the security team because the security team is paid a percentage out of the total premium that the protocol pays to Sherlock AND the security team determines the premium price as well. This means that the security team is in theory incentivized to provide a high premium price for a protocol, which would also be beneficial for the Sherlock treasury and for the stakers. However, in practice the premium prices need to be competitive on the DeFi insurance market, otherwise, protocols will not pay it.

LowStaker Funds Are Reinvested On Other DeFi PlatformsAcknowledged

The funds deposited by *stakers* with the purpose of covering platforms in case of a hack are reinvested on other DeFi platforms to increase *staker* yield. This puts the reinvested funds at risk of getting stolen by any hacks or insolvency of the DeFi platforms that are used for investing. At the moment the only platform that is used is Aave and therefore the risk is Low. However, if other (less secure) platforms will be used in the future, then the risk might increase.

LowStrong Dependency On Block Numbers For FinancialsAcknowledged

There is a strong dependency on `block.number` for financial calculations in at least 31 places inside the code. Current trends of Dapps observe them migrated to Layer2 platforms compatible with Solidity contracts for speed and gas costs. Due to block times and `block.number` speed changes being totally different (usually much faster) in Layer2 chains, this can result in financials extremely disrupted in Layer2 if contracts are migrated in the current state to L2. A more certain impact, but of smaller size, will impact the deployed contracts on the future automated migration to Ethereum 2.0, as current block time is approximately 13.34 seconds but Ethereum 2.0 is designed for a block time of 12 seconds. This can result in tokenomics distorted for Ethereum 2.0 or malicious users leveraging a Layer2 deployments to obtain an unfair advantage over Layer1 users.

LowTransfers of Zero Coins AllowedAcknowledged

Functions `transferFrom()` and `transfer()` of `SherXERC20` allows for a valid transfer of a zero amount of token from any account to any account. This has not a severe impact but can generate false alerts on transferences from wallets, pollute logging systems, and generate wash trading to collect possible future rewards. This is allowed by the ERC20 specification. From [EIP-20](https://eips.ethereum.org/EIPS/eip-20): "Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer event."

LowUnchecked Assumption In `SherX`Acknowledged

The `SherX.doYield` function allows the caller to specify an `amount` of tokens that should be transferred from the `from` address to the `to` address. However, there is no explicit check inside this function, which ensures that the `amount <= ps.lockToken.balanceOf(from)`. This could lead to an inappropriate amount of tokens being used for computations of the `ineglible_yield_amount`.

LowUnused Protocol Manager and Agent VariablesAcknowledged

Functionality for `protocolManagers` and `protocolAgents` are set in L161-162 but never used. This makes the audit and maintenance of the code more difficult.

Contracts in scope

No deployed address is recorded for this audit.

The report names a repository or files. Open the report to see its scope.

Repository and files the report names (50)

  • contracts/facets/Manager.sol
  • contracts/interfaces/aaveV2/IProposalValidator.sol
  • contracts/facets/Payout.sol
  • contracts/interfaces/IManager.sol
  • contracts/util/RemoveMock.sol
  • contracts/ForeignLock.sol
  • contracts/interfaces/IGovDev.sol
  • contracts/interfaces/aaveV2/IAaveIncentivesController.sol
  • contracts/interfaces/aaveV2/IStakeAave.sol
  • contracts/facets/Gov.sol
  • contracts/interfaces/aaveV2/IAaveGovernanceV2.sol
  • contracts/NativeLock.sol
  • contracts/interfaces/IPoolBase.sol
  • contracts/interfaces/aaveV2/IGovernanceV2Helper.sol
  • contracts/interfaces/ISherXERC20.sol
  • contracts/util/StrategyMock.sol
  • contracts/interfaces/IGov.sol
  • contracts/interfaces/aaveV2/ILendingPoolAddressesProvider.sol
  • contracts/interfaces/aaveV2/IAaveDistributionManager.sol
  • contracts/interfaces/IRemove.sol
  • contracts/libraries/LibPool.sol
  • contracts/interfaces/ISherlock.sol
  • contracts/facets/PoolStrategy.sol
  • contracts/facets/SherX.sol
  • contracts/libraries/LibSherXERC20.sol
  • contracts/interfaces/aaveV2/IAToken.sol
  • contracts/storage/SherXERC20Storage.sol
  • contracts/interfaces/ISherX.sol
  • contracts/interfaces/IPoolStrategy.sol
  • contracts/facets/SherXERC20.sol
  • contracts/libraries/LibSherX.sol
  • contracts/facets/PoolOpen.sol
  • contracts/util/Import.sol
  • contracts/interfaces/aaveV2/MockAave.sol
  • contracts/interfaces/aaveV2/IExecutorWithTimelock.sol
  • contracts/facets/PoolBase.sol
  • contracts/facets/PoolDevOnly.sol
  • contracts/interfaces/IPayout.sol
  • contracts/util/ERC20Mock.sol
  • contracts/storage/GovStorage.sol
  • contracts/strategies/AaveV2.sol
  • contracts/interfaces/ILock.sol
  • contracts/storage/PoolStorage.sol
  • contracts/facets/GovDev.sol
  • contracts/storage/PayoutStorage.sol
  • contracts/interfaces/IPoolStake.sol
  • contracts/interfaces/aaveV2/ILendingPool.sol
  • contracts/interfaces/IStrategy.sol
  • contracts/storage/SherXStorage.sol
  • contracts/interfaces/aaveV2/DataTypes.sol

Part of Sherlock’s security record

Sherlock
Audits1 audit by 1 firmLast audit Aug 2021, by Quantstamp.
Critical findingsNo open critical findingsIn 1 report.
Open Sherlock’s security record

Security firm

Quantstamp

236 projects reviewed · 332 reports · latest Oct 2026

See Quantstamp’s audits

Something wrong on this page? A missing report, a wrong date, a finding that was fixed since. Tell us and we check it against its source.

Tell us