## Incorrect rounding behavior in `router::get_coin_in_with_fees`

### Description

In the function `router::get_coin_in_with_fees`

, the result is rounded up incorrectly for both stable and uncorrelated curves, which can lead to an undue amount being paid in fees.

The formula for rounding up integer division is `(n - 1)/d + 1`

for `n > 0`

.

```
let coin_in = (stable_curve::coin_in(
(coin_out as u128),
scale_out,
scale_in,
(reserve_out as u128),
(reserve_in as u128),
) as u64) + 1;
(coin_in * fee_scale / fee_multiplier) + 1
```

The stable curve branch of `router::get_coin_in_with_fees`

does not correctly implement the formula stated above.

```
let coin_in = math::mul_div(
coin_out, // y
reserve_in * fee_scale, // rx * 1000
new_reserves_out // (ry - y) * 997
) + 1;
```

Furthermore, the uncorrelated curve branch also incorrectly implements the formula stated above.

### Impact

For certain swap amounts, a user could end up paying more in fees than would be accurate.

### Recommendations

In the case of the stable curve branch of `router::get_coin_in_with_fees`

, the code should be rewritten to adhere to the rounded up integer division formula.

```
let coin_in = (stable_curve::coin_in(
(coin_out as u128),
scale_out,
scale_in,
(reserve_out as u128),
(reserve_in as u128),
) as u64);
let n = coin_in * fee_scale;
if (n > 0) {
((n - 1) / fee_multiplier) + 1
} else {
0
}
```

Likewise, the uncorrelated curve branch also needs a revision.

```
// add to liquidswap::math
public fun mul_div_rounded_up(x: u64, y: u64, z: u64): u64 {
assert!(z != 0, ERR_DIVIDE_BY_ZERO);
let n = (x as u128) * (y as u128);
let r = if (n > 0) {
((n - 1) / (z as u128)) + 1
} else {
0
}
(r as u64)
}
let coin_in = math::mul_div_rounded_up(
coin_out, // y
reserve_in * fee_scale, // rx * 1000
new_reserves_out // (ry - y) * 997
);
```

### Remediation

Pontem Network fixed this issue in commit `0b01ed6`

↗