diff --git a/python/coinbase-agentkit/changelog.d/573.bugfix.md b/python/coinbase-agentkit/changelog.d/573.bugfix.md new file mode 100644 index 000000000..da892e3bf --- /dev/null +++ b/python/coinbase-agentkit/changelog.d/573.bugfix.md @@ -0,0 +1 @@ +Fixed bug in Morpho action provider to allow depositing ERC20 tokens of variable decimal precision diff --git a/python/coinbase-agentkit/coinbase_agentkit/action_providers/morpho/morpho_action_provider.py b/python/coinbase-agentkit/coinbase_agentkit/action_providers/morpho/morpho_action_provider.py index 74a1b4e80..4188c80cb 100644 --- a/python/coinbase-agentkit/coinbase_agentkit/action_providers/morpho/morpho_action_provider.py +++ b/python/coinbase-agentkit/coinbase_agentkit/action_providers/morpho/morpho_action_provider.py @@ -7,6 +7,7 @@ from coinbase_agentkit.action_providers.action_decorator import create_action from coinbase_agentkit.action_providers.action_provider import ActionProvider +from coinbase_agentkit.action_providers.erc20.constants import ERC20_ABI from coinbase_agentkit.action_providers.morpho.constants import METAMORPHO_ABI from coinbase_agentkit.action_providers.morpho.schemas import ( MorphoDepositSchema, @@ -60,7 +61,14 @@ def deposit(self, wallet_provider: EvmWalletProvider, args: dict[str, Any]) -> s return "Error: Assets amount must be greater than 0" try: - atomic_assets = Web3.to_wei(assets, "ether") + decimals = wallet_provider.read_contract( + contract_address=args["token_address"], + abi=ERC20_ABI, + function_name="decimals", + args=[], + ) + + atomic_assets = int(assets * (10**decimals)) try: approve( diff --git a/python/coinbase-agentkit/tests/action_providers/morpho/test_morpho_action_provider.py b/python/coinbase-agentkit/tests/action_providers/morpho/test_morpho_action_provider.py index 9e75732c7..c9645fba1 100644 --- a/python/coinbase-agentkit/tests/action_providers/morpho/test_morpho_action_provider.py +++ b/python/coinbase-agentkit/tests/action_providers/morpho/test_morpho_action_provider.py @@ -10,6 +10,7 @@ MOCK_TOKEN_ADDRESS = "0x0987654321098765432109876543210987654321" MOCK_RECEIVER = "0x5555555555555555555555555555555555555555" MOCK_TX_HASH = "0xabcdef1234567890" +MOCK_DECIMALS = 18 # Deposit Tests @@ -17,6 +18,7 @@ def test_morpho_deposit_success(): """Test successful morpho deposit with valid parameters.""" mock_wallet = MagicMock() mock_wallet.send_transaction.return_value = MOCK_TX_HASH + mock_wallet.read_contract.return_value = MOCK_DECIMALS with patch( "coinbase_agentkit.action_providers.morpho.morpho_action_provider.approve" diff --git a/typescript/.changeset/chubby-squids-cover.md b/typescript/.changeset/chubby-squids-cover.md new file mode 100644 index 000000000..3742fe73a --- /dev/null +++ b/typescript/.changeset/chubby-squids-cover.md @@ -0,0 +1,5 @@ +--- +"@coinbase/agentkit": patch +--- + +Fixed bug in Morpho action provider to allow depositing ERC20 tokens of variable decimal precision diff --git a/typescript/agentkit/src/action-providers/morpho/morphoActionProvider.test.ts b/typescript/agentkit/src/action-providers/morpho/morphoActionProvider.test.ts index dac1d7dec..7192e3064 100644 --- a/typescript/agentkit/src/action-providers/morpho/morphoActionProvider.test.ts +++ b/typescript/agentkit/src/action-providers/morpho/morphoActionProvider.test.ts @@ -11,6 +11,7 @@ const MOCK_RECEIVER_ID = "0x9876543210987654321098765432109876543210"; const MOCK_TOKEN_ADDRESS = "0x4200000000000000000000000000000000000006"; const MOCK_TX_HASH = "0xabcdef1234567890"; const MOCK_RECEIPT = { status: 1, blockNumber: 1234567 }; +const MOCK_DECIMALS = 18; jest.mock("../../utils"); const mockApprove = approve as jest.MockedFunction; @@ -25,6 +26,7 @@ describe("Morpho Action Provider", () => { getNetwork: jest.fn().mockReturnValue({ protocolFamily: "evm", networkId: "1" }), sendTransaction: jest.fn().mockResolvedValue(MOCK_TX_HASH as `0x${string}`), waitForTransactionReceipt: jest.fn().mockResolvedValue(MOCK_RECEIPT), + readContract: jest.fn().mockResolvedValue(MOCK_DECIMALS), } as unknown as jest.Mocked; mockApprove.mockResolvedValue("Approval successful"); diff --git a/typescript/agentkit/src/action-providers/morpho/morphoActionProvider.ts b/typescript/agentkit/src/action-providers/morpho/morphoActionProvider.ts index 760f25131..88e2731a7 100644 --- a/typescript/agentkit/src/action-providers/morpho/morphoActionProvider.ts +++ b/typescript/agentkit/src/action-providers/morpho/morphoActionProvider.ts @@ -1,7 +1,7 @@ import { z } from "zod"; import { Decimal } from "decimal.js"; -import { encodeFunctionData, parseEther } from "viem"; - +import { encodeFunctionData, Hex, parseUnits } from "viem"; +import { abi } from "../erc20/constants"; import { ActionProvider } from "../actionProvider"; import { EvmWalletProvider } from "../../wallet-providers"; import { CreateAction } from "../actionDecorator"; @@ -59,7 +59,14 @@ Important notes: } try { - const atomicAssets = parseEther(args.assets); + const decimals = await wallet.readContract({ + address: args.tokenAddress as Hex, + abi, + functionName: "decimals", + args: [], + }); + + const atomicAssets = parseUnits(args.assets, decimals); const approvalResult = await approve( wallet,