OriginProtocol / OriginProtocol/origin-dollar

[Security] CEI Violation in removeStrategy() - Reentrancy Allows Unlimited OUSD Minting

Open
#2,949 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Solidity
Stars
152
Forks
115
Avg merge
3d 20h
Merged PRs (30d)
17

Description

Summary

Severity: Medium-High
PoC: Available
Impact: Unlimited OUSD token minting without backing, supply inflation attack

Description

In VaultAdmin.sol, the removeStrategy() function violates the Checks-Effects-Interactions (CEI) pattern. The external call strategy.withdrawAll() is executed BEFORE the strategy state is updated to isSupported = false.

function removeStrategy(address _addr) external onlyGovernor {
    require(strategies[_addr].isSupported, "Not supported");
    IStrategy(_addr).withdrawAll();       // INTERACTION - BEFORE state update
    strategies[_addr].isSupported = false; // EFFECT - TOO LATE
}

If the strategy is mint-whitelisted, its withdrawAll() can call back into the vault via mintForStrategy() to mint OUSD tokens while still being whitelisted. This allows:

  1. Attacker-controlled strategy calls withdrawAll()
  2. During withdrawal, strategy re-enters vault to mint OUSD
  3. Since strategy is still whitelisted, mint succeeds
  4. Attacker drains underlying assets with unbacked OUSD

Full PoC

Complete Foundry PoC available upon request.

Fix

function removeStrategy(address _addr) external onlyGovernor {
    require(strategies[_addr].isSupported, "Not supported");
    strategies[_addr].isSupported = false;  // Move BEFORE withdrawAll
    IStrategy(_addr).withdrawAll();
}

Reported by: laolaoqi

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in VaultAdmin.sol at removeStrategy() and trace the external strategy.withdrawAll() call, the strategies[_addr].isSupported state, and mintForStrategy(). Use the reported reentrancy scenario or the available Foundry PoC to verify that minting cannot occur during strategy removal. Done means the strategy is no longer eligible before withdrawal and the PoC no longer succeeds.

Written by the indexing model from the issue text.

Assessment

Tech stack
solidity
Domain
blockchain, security
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.