Description:Description\
There is a potential arbitrage opportunity in the deposit/withdraw flow due to how asset/share conversion is handled. The issue lies in the price calculation mechanism between deposits and withdrawals.
function deposit(uint256 assets, address receiver) public returns (uint256 shares) {
// @FOUND - Deposit uses convertToShares() which can be manipulated through rapid flows
shares = convertToShares(assets); // @FOUND - Direct share conversion without slippage protection allows price manipulation
usde.burn(msg.sender, assets);
_mint(receiver, shares);
emit Deposit(msg.sender, receiver, assets, shares);
}
function withdraw(uint256 assets, address receiver, address owner) public returns (uint256 shares) {
// @FOUND - Withdraw uses the same convertToShares() calculation, enabling profit through price manipulation
shares = convertToShares(assets); // @FOUND - Using same conversion rate enables arbitrage through rapid cycling
if (owner != msg.sender) _spendAllowance(owner, msg.sender, shares);
_burn(owner, shares);
usde.mint(receiver, assets);
emit Withdraw(msg.sender, receiver, owner, assets, shares);
}
The contract uses the same convertToShares() function for both deposit and withdraw calculations
This creates a potential arbitrage window where a user could:
Deposit assets when the share price is low
Immediately withdraw when share price updates
Profit from the price difference between deposit and withdrawal
Because:
Both functions use the same convertToShares() calculation without any spread or slippage protection
The share price can be manipulated through rapid deposit/withdraw cycles
Arbitrage bots can exploit price updates between deposit and withdrawal
Users can extract value from the protocol by timing their transactions around price updates
No cooldown period exists between deposits and withdrawals
The impact is severe as it allows systematic value extraction from the protocol through arbitrage, potentially depleting protocol reserves and harming other users' positions.
Attack Scenario\
A malicious actor can exploit this vulnerability through the following steps:
Github username: @0xbrett8571 Twitter username: 0xbrett8571 Submission hash (on-chain): 0x8247015e27cccb058c7f0df2f800d056c6e1cd9afa81474cbb7ed0541c94cc85 Severity: medium
Description: Description\ There is a potential arbitrage opportunity in the deposit/withdraw flow due to how asset/share conversion is handled. The issue lies in the price calculation mechanism between deposits and withdrawals.
convertToShares()
function for both deposit and withdraw calculationsThis creates a potential arbitrage window where a user could:
Because:
convertToShares()
calculation without any spread or slippage protectionThe impact is severe as it allows systematic value extraction from the protocol through arbitrage, potentially depleting protocol reserves and harming other users' positions.
Attack Scenario\ A malicious actor can exploit this vulnerability through the following steps:
// Step 2: Share price manipulation through market actions // Price updates to 1.1 USDE/EUI
// Step 3: Immediate withdrawal attacker.withdraw(1100 USDE); // Burns 1000 EUI // Profit: 100 USDE
Initial deposit of 1000 ether
Price manipulation to 1.1x
Withdrawal resulting in 1100 ether
Net profit of 100 ether
Revised Code File (Optional)
function withdraw(uint256 assets, address receiver, address owner, uint256 maxShares) public returns (uint256 shares) {