Sherlock contest - kirk-baird's results

Decentralized exploit protection.

General Information

Platform: Code4rena

Start Date: 20/01/2022

Pot Size: $80,000 USDC

Total HM: 5

Participants: 37

Period: 7 days

Judge: Jack the Pug

Total Solo HM: 1

Id: 76

League: ETH

Sherlock

Findings Distribution

Researcher Performance

Rank: 4/37

Findings: 2

Award: $7,330.80

🌟 Selected for report: 1

πŸš€ Solo Findings: 0

Findings Information

🌟 Selected for report: kirk-baird

Also found by: static

Labels

bug
2 (Med Risk)
disagree with severity
resolved
sponsor confirmed

Awards

7304.7588 USDC - $7,304.76

External Links

Handle

kirk-baird

Vulnerability details

Impact

This is a reentrancy vulnerability that would allow the attacker to drain the entire SHER balance of the contract.

Note: this attack requires gaining control of execution sher.transfer() which will depend on the implementation of the SHER token. Control may be gained by the attacker if the contract implements ERC777 or otherwise makes external calls during transfer().

Proof of Concept

See _sendSherRewards

  function _sendSherRewardsToOwner(uint256 _id, address _nftOwner) internal {
    uint256 sherReward = sherRewards_[_id];
    if (sherReward == 0) return;

    // Transfers the SHER tokens associated with this NFT ID to the address of the NFT owner
    sher.safeTransfer(_nftOwner, sherReward);
    // Deletes the SHER reward mapping for this NFT ID
    delete sherRewards_[_id];
  }

Here sherRewards are deleted after the potential external call is made in sher.safeTransfer(). As a result if an attacker reenters this function sherRewards_ they will still maintain the original balance of rewards and again transfer the SHER tokens.

As _sendSherRewardsToOwner() is internal the attack can be initiated through the external function ownerRestake() see here.

Steps to produce the attack:

  1. Deploy attack contract to handle reenterancy
  2. Call initialStake() from the attack contract with the smallest period
  3. Wait for period amount of time to pass
  4. Have the attack contract call ownerRestake(). The attack contract will gain control of the (See note above about control flow). This will recursively call ownerRestake() until the balance of Sherlock is 0 or less than the user's reward amount. Then allow reentrancy loop to unwind and complete.

Tools Used

n/a

Reentrancy can be mitigated by one of two solutions.

The first option is to add a reentrancy guard like nonReentrant the is used in SherlockClaimManager.sol.

The second option is to use the checks-effects-interactions pattern. This would involve doing all validation checks and state changes before making any potential external calls. For example the above function could be modified as follows.

  function _sendSherRewardsToOwner(uint256 _id, address _nftOwner) internal {
    uint256 sherReward = sherRewards_[_id];
    if (sherReward == 0) return;

    // Deletes the SHER reward mapping for this NFT ID
    delete sherRewards_[_id];

    // Transfers the SHER tokens associated with this NFT ID to the address of the NFT owner
    sher.safeTransfer(_nftOwner, sherReward);
  }

Additionally the following functions are not exploitable however should be updated to use the check-effects-interations pattern.

  • Sherlock._redeemShares() should do _transferTokensOut() last.
  • Sherlock.initialStake() should do token.safeTransferFrom(msg.sender, address(this), _amount); last
  • SherClaim.add() should do sher.safeTransferFrom(msg.sender, address(this), _amount); after updating userClaims
  • SherlockProtocolManager.depositToActiveBalance() should do token.safeTransferFrom(msg.sender, address(this), _amount); after updating activeBalances

#0 - Evert0x

2022-02-03T21:31:23Z

Good find. I think it's med-risk as it depends on the implementation of SHER token (does it allow callbacks)

#1 - jack-the-pug

2022-03-10T15:44:20Z

Downgrade to Med as the SHER token is a known token that currently comes with no such hooks like ERC777.

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