# setWeight() Logic error

Inverted comparison and swapped mulDiv args in UlyssesPool.setWeight() misredistribute bandwidth across pools, corrupting AMM accounting when weights change.

- Payout: Contest reward
- Severity: high
- Program: Maia DAO Ecosystem
- Credited: bin2chen
- Disclosed: 2023-09-18
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-05-maia-findings/issues/766
- Library page: https://bugbountylibrary.com/r/c4%3A2023-05-maia%3AH-03
- Tags: domain:web3 impact:integrity kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** UlyssesPool.sol setWeight() AMM bandwidth accounting
**Root cause:** The branch condition `oldTotalWeights > newTotalWeights` is inverted relative to the redistribution logic it guards, and the mulDivUp arguments are swapped, so bandwidth is scaled in the wrong direction and leftover bandwidth is misallocated.
**Steps:**
1. Read setWeight() at UlyssesPool.sol#L223; note the if-branch redistributes bandwidth from other pools to the changed pool, which only makes sense when total weight increases.
2. Observe condition is `oldTotalWeights > newTotalWeights` (decrease case) — inverted.
3. Observe `oldBandwidth.mulDivUp(oldTotalWeights, newTotalWeights)` scales the wrong way; should be `mulDivUp(newTotalWeights, oldTotalWeights)`.
4. Observe leftover bandwidth is dumped entirely onto the last index rather than distributed proportionally by weight, and the last-index check `i == length-1` can skip the changed pool.
5. Call setWeight() with a new weight to trigger incorrect bandwidthStateList updates.
**How found:** Code review of the weight-update branch: the author noticed the redistribution logic inside the `if` only fits the weight-increase case, contradicting the comparison, then traced the mulDivUp scaling and leftover distribution for further errors.
**Insight:** When auditing weight/share rebalancing, check that the branch condition matches the direction of the scaling math and that mulDivUp numerator/denominator are ordered so the changed pool's share moves the correct way; also verify leftover dust is distributed proportionally, not dumped on the last index.
