Open hats-bug-reporter[bot] opened 1 week ago
Price updates are done quite rarely, according to a commit/update period, by a trusted oracle; committing an updated price is open to everyone, that's true, but we can assume user is aware of the mechanism. YieldOracle update mechanism could have been better but, but for a simple first version, this is the intended design.
I'm still willing to consider it as a reason to improve a bit the YieldOracle price update mechanism, we'll mark this as low tier and think more about it.
I believe that lack of slippage protection is a high because it can lead to direct loss of user funds through unfavorable price execution.
The issue is not prevented by the trust in the oracle, as the issue occurs between price update and transaction execution.
Github username: -- Twitter username: -- Submission hash (on-chain): 0x20763a0957531d9af1e815ae69150b91028939be72f470e23fd42469f634386e Severity: high
Description: Description\ The InvestToken contract implements the ERC4626 vault standard but lacks slippage protection in its deposit, mint, withdraw, and redeem functions.
These functions rely on the current price from the yieldOracle without allowing users to specify minimum output amounts.
Due to potential price changes between transaction submission and execution, users might receive fewer shares/assets than expected, leading to significant value loss.
For example, in the deposit function:
The function calculates shares based on the current price but doesn't let users specify a minimum acceptable amount of shares.
Attack Scenario\ Alice wants to deposit 10,000 USDE when 1 USDE = 1 share (according to previewDeposit)
Alice submits a transaction expecting 10,000 shares
Before Alice's transaction is mined, the price changes significantly due to an oracle update
When Alice's transaction executes, she receives significantly fewer shares than expected
A malicious actor could manipulate this by:
Monitoring the mempool for large deposit/withdraw transactions
Front-running with oracle price updates
Profiting from users receiving unfavorable rates
Attachments
Proof of Concept (PoC) File
Revised Code File (Optional)
contract InvestToken { /**
@return shares Amount of shares minted */ function deposit( uint256 assets, address receiver, uint256 minSharesOut ) public returns (uint256 shares) { require(receiver != address(0), "Invalid receiver"); require(assets > 0, "Invalid amount");
}
/**
@return shares Amount of shares burned */ function withdraw( uint256 assets, address receiver, address owner, uint256 maxSharesIn ) public returns (uint256 shares) { require(receiver != address(0), "Invalid receiver"); require(assets > 0, "Invalid amount");
}
// Similar changes should be made to mint() and redeem() functions }