# UlyssesToken.setWeights(...) can cause user loss of assets on vault deposits/withdrawals

UlyssesToken.setWeights can change asset weights between a user's previewDeposit and deposit, causing the user to receive fewer shares and lose excess deposited assets.

- Payout: Contest reward
- Severity: medium
- Program: Maia DAO Ecosystem
- Credited: 0xTheC0der
- Disclosed: 2023-09-18
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-05-maia-findings/issues/281
- Library page: https://bugbountylibrary.com/r/c4%3A2023-05-maia%3AM-34
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:race-window technique:source-review vuln:accounting-error vuln:business-logic vuln:race-condition

**Target:** UlyssesToken multi-asset ERC-4626 vault (deposit/withdraw)
**Root cause:** Multi-asset vault converts deposit amounts to shares by taking the minimum across assets and withdraw shares by taking the maximum; changing weights via setWeights between preview and execution makes the user's asset ratio mismatch the new weights, so excess assets are donated and fewer shares received.
**Steps:**
1. Deploy UlyssesToken vault with N weighted assets.
2. User computes assetsAmounts proportional to current weights and calls `previewDeposit(assetsAmounts)` to get expectedShares.
3. Owner calls `setWeights(weights)` doubling weights[0] before the user's `deposit(assetsAmounts)` lands (mempool ordering).
4. User's `deposit(assetsAmounts)` executes; `convertToShares` takes min across assets, returning fewer shares than expected.
5. `previewRedeem(receivedShares)` returns less than deposited for non-asset[0] assets; excess is unrecoverable.
**How found:** Reasoned that ERC-4626 single-asset share/asset convertibility breaks with multiple weighted assets; noted deposit uses min-of-shares and withdraw uses max-of-shares, then hypothesized that mutable weights via setWeights create a time-sensitivity/race window between preview and execution.
**Exploitation:** Requires the vault owner (or privileged setWeights caller) to reorder setWeights ahead of a pending user deposit/withdraw; user's tx then executes against stale asset ratios, donating excess assets to the vault. No external attacker capital needed; loss is involuntary user donation.
**Insight:** For multi-asset or weighted vaults, check whether admin-mutable parameters (weights, fees, ratios) can change between a user's preview/quote and execution; min/max rounding across assets turns that ordering into silent user loss.
