Morpho withdraw action hardcodes 18 decimals
- Dominant language
- TypeScript
- Stars
- 1.3k
- Forks
- 815
- Avg merge
- 13h 31m
- Merged PRs (30d)
- 2
Description
### Language Affected
- [x] Python
- [ ] TypeScript
### 🐛 Describe the bug
`MorphoActionProvider.withdraw()` uses `Web3.to_wei(assets, "ether")` to convert the `assets` input to atomic units. This hardcodes 18 decimals regardless of the actual token's decimals, so it produces incorrect amounts for any token that isn't 18 decimals (e.g. USDC with 6 decimals).
Meanwhile, `MorphoActionProvider.deposit()` correctly fetches the token's decimals on-chain and does `int(assets * (10**decimals))`.
The descriptions are also inconsistent — deposit says "whole units", withdraw says "atomic units" — but the code for withdraw treats the input as whole units anyway (it multiplies by 10^18).
```python
from coinbase_agentkit import morpho_action_provider
provider = morpho_action_provider()
# deposit (line 64-71) — CORRECT: fetches actual token decimals
# decimals = wallet_provider.read_contract(..., function_name="decimals")
# atomic_assets = int(assets * (10**decimals))
# withdraw (line 125) — BUG: hardcodes 18 decimals
# atomic_assets = Web3.to_wei(assets, "ether") # always 10^18
```
**Example:** Withdrawing 100 USDC (6 decimals) from a Morpho vault:
- Expected atomic amount: `100 * 10^6 = 100_000_000`
- Actual atomic amount: `100 * 10^18 = 100_000_000_000_000_000_000` (12 orders of magnitude too large)
The fix would be to add `token_address` to `MorphoWithdrawSchema` and fetch decimals dynamically, matching the deposit implementation:
```python
# withdraw should do the same as deposit:
decimals = wallet_provider.read_contract(
contract_address=args["token_address"],
abi=ERC20_ABI,
function_name="decimals",
args=[],
)
atomic_assets = int(assets * (10**decimals))
```
The description should also be updated to say "whole units" to match deposit.
### Versions
```
Python 3.12.9
Name: coinbase-agentkit
Version: 0.7.4
```
Contributor guide
Assessment
This issue has not been assessed yet.