# [ghost-dao-contracts] `BondDepository.deposit` double-charges partial native-ETH payments on WETH-quoted markets
`deposit()` in `src/BondDepository.sol` supports paying bonds with native ETH
on WETH-quoted markets. Sending partial ETH (`0 < msg.value < amount`) charges
the depositor twice: the ETH is wrapped and forwarded to the treasury, then the
full `amount` is pulled via `transferFrom` on top of it. The overpaid ETH is
unrecoverable.
```solidity
IWETH9(WETH).deposit{value: msg.value}();
IERC20(WETH).safeTransfer(TREASURY, msg.value);
if (msg.value < amount || market.quoteToken != WETH) {
IERC20(market.quoteToken).safeTransferFrom(msg.sender, TREASURY, amount);
}
```
The `transferFrom` should pull `amount - msg.value` on a WETH market. It
currently pulls the full `amount` whenever `msg.value < amount`.
This native-payment path was added by the ghostchain team in `6fec7ed`
(“ability to purchase bond with native coin”), replacing a plain
`transferFrom(amount)` — the double-charge is a bug in that custom feature,
not inherited behavior.
## Reproduction
Foundry test against `ghost-dao-contracts @ b87dff4`. WETH-quoted market, bond
amount 7 ether, `msg.value` 3 ether:
```solidity
uint256 tBefore = weth.balanceOf(address(treasury));
depository.deposit{value: 3 ether}(0, 7 ether, type(uint256).max, ALICE);
uint256 gain = weth.balanceOf(address(treasury)) - tBefore;
```
```
treasury gain: 10000000000000000000 // 10 ether credited for a 7-ether bond
alice ETH spent: 3000000000000000000
alice WETH spent: 7000000000000000000 // full amount pulled via transferFrom
```
Control cases (correct behavior): exact ETH (`msg.value == amount`) forwards
exactly `amount` with no `transferFrom`; pure WETH (`msg.value == 0`) pulls
exactly `amount`.
## Impact
Permanent overpayment of `msg.value` for any depositor attaching partial ETH.
Requires the victim’s own transaction; the surplus goes to the treasury, not
an attacker. Severity: Medium.
## Fix
```solidity
IWETH9(WETH).deposit{value: msg.value}();
IERC20(WETH).safeTransfer(TREASURY, msg.value);
if (market.quoteToken == WETH) {
if (msg.value < amount) {
IERC20(WETH).safeTransferFrom(msg.sender, TREASURY, amount - msg.value);
} else if (msg.value > amount) {
IWETH9(WETH).withdraw(msg.value - amount);
payable(msg.sender).transfer(msg.value - amount);
}
} else {
if (msg.value > 0) revert DepositoryNoEthForTokenMarket();
IERC20(market.quoteToken).safeTransferFrom(msg.sender, TREASURY, amount);
}
```