https://github.com/OpenEdenHQ/openeden.vault.audit/tree/d18288e944df21729b18d430b2afec2da99b6287
The OpenEdenVaultV4 contract has completely removed on-chain checks for USDC/USD price peg and price feed freshness that were present in the previous version (V3). In V3, deposit, redemption, and withdrawal queue processing were all gated by a modifier (onlyValidPrice) that required USDC to remain within a configurable depeg threshold and the price feed to be fresh.
In V4, any user can deposit or redeem USDC at a hardcoded $1 rate, even if USDC has lost its peg (e.g., trading at $0.80 on secondary markets), as the contract no longer references any USDC/USD oracle. This exposes the protocol and all vault participants to share inflation and economic loss: attackers can arbitrage by depositing depegged USDC and redeeming for full-value assets, diluting the value of all shares in the vault.
// @audit-issue Lack of USDC peg/freshness guard in deposit/redeem logic
// V3 Example (removed in V4):
modifier onlyValidPrice() {
(, int256 answer1, , uint256 updateAt, ) = usdcUsdPriceFeed.latestRoundData();
require(block.timestamp - updateAt <= maxTimeDelay, "stale usdc answer!");
require(answer1 > 0, "should gt 0");
uint256 answer = uint256(answer1);
uint256 depeg = ...;
require(depeg <= max, "usdc and usd depeg!");
_;
}
function deposit(...) external onlyValidPrice { ... }
function redeem(...) external onlyValidPrice { ... }
function processWithdrawalQueue(...) external onlyValidPrice { ... }
// V4: All references to onlyValidPrice and usdcUsdPriceFeed removed.
// No on-chain USDC price/freshness checks exist.
V3 required all major user actions to pass USDC/USD price and staleness checks.
V4 has no such checks: deposits and redemptions always assume USDC = $1, regardless of actual market price or oracle feed state.
Attackers can deposit large amounts of depegged USDC (e.g., trading at $0.80), receive shares valued at $1/USDC, and later redeem for full-value assets once the peg is restored or through alternate redemption mechanisms.
Likelihood - Medium:
Impact - High:
Reintroduce On-Chain USDC Peg and Freshness Checks
Add a modifier (similar to V3's onlyValidPrice) on all deposit, redeem, and withdrawal queue processing entry points, enforcing that:
Example fix:
modifier onlyValidPrice() {
(, int256 answer1, , uint256 updateAt, ) = usdcUsdPriceFeed.latestRoundData();
require(block.timestamp - updateAt <= maxTimeDelay, "stale usdc answer!");
require(answer1 > 0, "bad price");
uint256 answer = uint256(answer1);
uint256 numerator = ONE > answer ? ONE - answer : answer - ONE;
uint256 denominator = (ONE + answer) / 2;
uint256 depeg = (numerator * ONE) / denominator;
uint256 max = (maxDepeg * ONE) / BPSUNIT;
require(depeg <= max, "usdc and usd depeg!");
_;
}
function deposit(...) external onlyValidPrice { ... }
function redeem(...) external onlyValidPrice { ... }
function processWithdrawalQueue(...) external onlyValidPrice { ... }
This ensures the protocol cannot be economically attacked using depegged USDC or stale price data.
1 . Deploy the OpenEdenVaultV4 contract Deploy OpenEdenVaultV4 with USDC (or mock USDC, 6 decimals) as the underlying token. Make sure the price feed address for USDC/USD is unset or not referenced anywhere in the contract logic.
2 . Simulate a USDC depeg event For testing, simply assume or configure your mock USDC token to have a market price of $0.80 (while the contract will always treat 1 USDC as $1).
3 . Acquire discounted USDC From a different account, acquire 1,000,000 USDC at $0.80 per token (simulate this by minting or transferring tokens).
4 . Approve and deposit depegged USDC
Approve the OpenEdenVaultV4 contract to spend your USDC, then call deposit(1_000_000e6, attacker).
5 . Verify shares received Check the attacker’s share balance. It should reflect a value near $1,000,000 (minus any fee), even though attacker only spent $800,000.
6 . Redeem shares when USDC returns to $1
Simulate a return to
$1 parity or redemption via redeemIns/redeem. Attacker receives close to $1,000,000 USDC.
7 . Validate economic impact