Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom Pineapple Newt - Lender group members can be prevented from burning their shares forever #24

Open
sherlock-admin4 opened this issue Dec 10, 2024 · 1 comment
Labels
Sponsor Confirmed The sponsor acknowledged this issue is valid Will Fix The sponsor confirmed this issue will be fixed

Comments

@sherlock-admin4
Copy link

Custom Pineapple Newt

High

Lender group members can be prevented from burning their shares forever

Summary

Summary

Adversaries can constantly reset the withdrawal delay of lender group members by performing 0-value transferFrom transactions to invoke the afterTokenTransfer hook.

Description

Currently there is a delay on withdrawals to prevent sandwich attacks in lender group contracts. Members must invoke prepareSharesForBurn by stating how many shares they want to burn and start an internal countdown. Afterwards, members invoke burnSharesToWithdrawEarnings which checks whether the delay passed in burn

    function burn(address _burner, uint256 _amount, uint256 withdrawDelayTimeSeconds) external onlyOwner {

        //require prepared 
        require(poolSharesPreparedToWithdrawForLender[_burner] >= _amount,"Shares not prepared for withdraw");
   @>   require(poolSharesPreparedTimestamp[_burner] <= block.timestamp - withdrawDelayTimeSeconds,"Shares not prepared for withdraw");
        

        //reset prepared   
        poolSharesPreparedToWithdrawForLender[_burner] = 0;
        poolSharesPreparedTimestamp[_burner] =  block.timestamp;
  


        _burn(_burner, _amount);
    }

This countdown is reset every time a member invokes a share transfer through the _afterTokenTransfer hook presumably to prevent users preparing shares in advance by transferring it between one another.

     function _afterTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal override {

         //reset prepared   
        poolSharesPreparedToWithdrawForLender[from] = 0;
        poolSharesPreparedTimestamp[from] =  block.timestamp;


    }

Adversaries can perform 0-value transferFrom transactions which will always pass as there are no 0-value checks in OZ's version 4.8 ERC20.sol used by the protocol. Users will have their countdown constantly reset thus being prevented from withdrawing forever or until a bribe is paid.

Root Cause

  • OpenZeppelin's ERC20.transferFrom has no 0-value input validation
  • LenderCommitmentGroupShares._afterTokenTransfer does not perform 0-value input either.

Internal pre-conditions

Group members must have invoked prepareSharesForBurn

External pre-conditions

None

Attack Path

  1. Group member invokes prepareSharesForBurn starting the countdown
  2. Adversary invokes transferFrom(victim, to, 0) minutes before the cooldown expires
  3. Cooldown and shares are reset because _afterTokenTransfer was triggered
  4. Group member is forced to re-prepare their shares
  5. Attacker repeats this continuously or until a bribe is paid

Impact

Lender commit group members will have their funds permanently locked in the contract

PoC

No response

Mitigation

Rewrite the _afterTokenTransfer hook to be skipped in case of amount = 0

@sherlock-admin3 sherlock-admin3 added Sponsor Confirmed The sponsor acknowledged this issue is valid Will Fix The sponsor confirmed this issue will be fixed labels Dec 12, 2024
@sherlock-admin2
Copy link

The protocol team fixed this issue in the following PRs/commits:
teller-protocol/teller-protocol-v2-audit-2024#76

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Sponsor Confirmed The sponsor acknowledged this issue is valid Will Fix The sponsor confirmed this issue will be fixed
Projects
None yet
Development

No branches or pull requests

3 participants