> ## Documentation Index
> Fetch the complete documentation index at: https://cosmos-docs-tweak-colors.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# WERC20

> Wrapped native token functionality enabling ERC20 representation of native tokens

## Overview

The WERC20 precompile provides a standardized way to wrap native EVM tokens, allowing them to be used as ERC20-compatible tokens within smart contracts. This precompile ensures a 1:1 backing between the native token and its wrapped counterpart, enabling seamless interaction with DeFi protocols and other dApps that rely on the ERC20 standard.

**Precompile Address**: Dynamic (assigned per wrapped token)
**Related Module**: Token wrapping utilities

## Methods

### `deposit`

Deposits native tokens in exchange for wrapped ERC20 tokens.

### `withdraw`

Withdraws native tokens from wrapped ERC20 tokens.

### `totalSupply`

Returns the total supply of the wrapped token.

<CodeGroup>
  ```javascript Ethers.js expandable lines
  import { ethers } from "ethers";

  // Connect to the network
  const provider = new ethers.JsonRpcProvider("<RPC_URL>");

  // The WERC20 precompile address is dynamically assigned
  const werc20PrecompileAddress = "<WERC20_PRECOMPILE_ADDRESS>";
  const werc20Abi = ["function totalSupply() view returns (uint256)"];

  // Create a contract instance
  const contract = new ethers.Contract(werc20PrecompileAddress, werc20Abi, provider);

  async function getTotalSupply() {
    try {
      const totalSupply = await contract.totalSupply();
      console.log("Total Supply:", totalSupply.toString());
    } catch (error) {
      console.error("Error fetching total supply:", error);
    }
  }

  getTotalSupply();
  ```

  ```bash cURL expandable lines
  # Note: Replace <RPC_URL> and <WERC20_PRECOMPILE_ADDRESS> with your actual data.
  # The WERC20 precompile address is dynamically assigned.
  curl -X POST --data '{
      "jsonrpc": "2.0",
      "method": "eth_call",
      "params": [
          {
              "to": "<WERC20_PRECOMPILE_ADDRESS>",
              "data": "0x18160ddd"
          },
          "latest"
      ],
      "id": 1
  }' -H "Content-Type: application/json" <RPC_URL>
  ```
</CodeGroup>

### `balanceOf`

Returns the wrapped token balance for a specific account.

<CodeGroup>
  ```javascript Ethers.js expandable lines
  import { ethers } from "ethers";

  // Connect to the network
  const provider = new ethers.JsonRpcProvider("<RPC_URL>");

  // The WERC20 precompile address is dynamically assigned
  const werc20PrecompileAddress = "<WERC20_PRECOMPILE_ADDRESS>";
  const accountAddress = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"; // Placeholder
  const werc20Abi = ["function balanceOf(address account) view returns (uint256)"];

  // Create a contract instance
  const contract = new ethers.Contract(werc20PrecompileAddress, werc20Abi, provider);

  async function getBalance() {
    try {
      const balance = await contract.balanceOf(accountAddress);
      console.log(`Balance of ${accountAddress}:`, balance.toString());
    } catch (error) {
      console.error("Error fetching balance:", error);
    }
  }

  getBalance();
  ```

  ```bash cURL expandable lines
  # Note: Replace <RPC_URL>, <WERC20_PRECOMPILE_ADDRESS>, and the placeholder address with your actual data.
  curl -X POST --data '{
      "jsonrpc": "2.0",
      "method": "eth_call",
      "params": [
          {
              "to": "<WERC20_PRECOMPILE_ADDRESS>",
              "data": "0x70a08231000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa96045"
          },
          "latest"
      ],
      "id": 1
  }' -H "Content-Type: application/json" <RPC_URL>
  ```
</CodeGroup>

### `transfer`

Transfers wrapped tokens to a specified address.

### `approve`

Approves a spender to transfer wrapped tokens on behalf of the caller.

### `transferFrom`

Transfers wrapped tokens from one address to another, using an allowance.

### `allowance`

Returns the remaining amount of tokens a spender is allowed to transfer on behalf of an owner.

<CodeGroup>
  ```javascript Ethers.js expandable lines
  import { ethers } from "ethers";

  // Connect to the network
  const provider = new ethers.JsonRpcProvider("<RPC_URL>");

  // The WERC20 precompile address is dynamically assigned
  const werc20PrecompileAddress = "<WERC20_PRECOMPILE_ADDRESS>";
  const ownerAddress = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"; // Placeholder
  const spenderAddress = "0x27f320b7280911c7987a421a8138997a48d4b315"; // Placeholder
  const werc20Abi = ["function allowance(address owner, address spender) view returns (uint256)"];

  // Create a contract instance
  const contract = new ethers.Contract(werc20PrecompileAddress, werc20Abi, provider);

  async function getAllowance() {
    try {
      const allowance = await contract.allowance(ownerAddress, spenderAddress);
      console.log("Allowance:", allowance.toString());
    } catch (error) {
      console.error("Error fetching allowance:", error);
    }
  }

  getAllowance();
  ```

  ```bash cURL expandable lines
  # Note: Replace <RPC_URL>, <WERC20_PRECOMPILE_ADDRESS>, and the placeholder addresses with your actual data.
  curl -X POST --data '{
      "jsonrpc": "2.0",
      "method": "eth_call",
      "params": [
          {
              "to": "<WERC20_PRECOMPILE_ADDRESS>",
              "data": "0xdd62ed3e000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa9604500000000000000000000000027f320b7280911c7987a421a8138997a48d4b315"
          },
          "latest"
      ],
      "id": 1
  }' -H "Content-Type: application/json" <RPC_URL>
  ```
</CodeGroup>

### `name`

Returns the name of the wrapped token.

<CodeGroup>
  ```javascript Ethers.js expandable lines
  import { ethers } from "ethers";

  // Connect to the network
  const provider = new ethers.JsonRpcProvider("<RPC_URL>");

  // The WERC20 precompile address is dynamically assigned
  const werc20PrecompileAddress = "<WERC20_PRECOMPILE_ADDRESS>";
  const werc20Abi = ["function name() view returns (string)"];

  // Create a contract instance
  const contract = new ethers.Contract(werc20PrecompileAddress, werc20Abi, provider);

  async function getName() {
    try {
      const name = await contract.name();
      console.log("Token Name:", name);
    } catch (error) {
      console.error("Error fetching name:", error);
    }
  }

  getName();
  ```

  ```bash cURL expandable lines
  # Note: Replace <RPC_URL> and <WERC20_PRECOMPILE_ADDRESS> with your actual data.
  curl -X POST --data '{
      "jsonrpc": "2.0",
      "method": "eth_call",
      "params": [
          {
              "to": "<WERC20_PRECOMPILE_ADDRESS>",
              "data": "0x06fdde03"
          },
          "latest"
      ],
      "id": 1
  }' -H "Content-Type: application/json" <RPC_URL>
  ```
</CodeGroup>

### `symbol`

Returns the symbol of the wrapped token.

<CodeGroup>
  ```javascript Ethers.js expandable lines
  import { ethers } from "ethers";

  // Connect to the network
  const provider = new ethers.JsonRpcProvider("<RPC_URL>");

  // The WERC20 precompile address is dynamically assigned
  const werc20PrecompileAddress = "<WERC20_PRECOMPILE_ADDRESS>";
  const werc20Abi = ["function symbol() view returns (string)"];

  // Create a contract instance
  const contract = new ethers.Contract(werc20PrecompileAddress, werc20Abi, provider);

  async function getSymbol() {
    try {
      const symbol = await contract.symbol();
      console.log("Token Symbol:", symbol);
    } catch (error) {
      console.error("Error fetching symbol:", error);
    }
  }

  getSymbol();
  ```

  ```bash cURL expandable lines
  # Note: Replace <RPC_URL> and <WERC20_PRECOMPILE_ADDRESS> with your actual data.
  curl -X POST --data '{
      "jsonrpc": "2.0",
      "method": "eth_call",
      "params": [
          {
              "to": "<WERC20_PRECOMPILE_ADDRESS>",
              "data": "0x95d89b41"
          },
          "latest"
      ],
      "id": 1
  }' -H "Content-Type: application/json" <RPC_URL>
  ```
</CodeGroup>

### `decimals`

Returns the number of decimals used by the wrapped token.

<CodeGroup>
  ```javascript Ethers.js expandable lines
  import { ethers } from "ethers";

  // Connect to the network
  const provider = new ethers.JsonRpcProvider("<RPC_URL>");

  // The WERC20 precompile address is dynamically assigned
  const werc20PrecompileAddress = "<WERC20_PRECOMPILE_ADDRESS>";
  const werc20Abi = ["function decimals() view returns (uint8)"];

  // Create a contract instance
  const contract = new ethers.Contract(werc20PrecompileAddress, werc20Abi, provider);

  async function getDecimals() {
    try {
      const decimals = await contract.decimals();
      console.log("Token Decimals:", decimals.toString());
    } catch (error) {
      console.error("Error fetching decimals:", error);
    }
  }

  getDecimals();
  ```

  ```bash cURL expandable lines
  # Note: Replace <RPC_URL> and <WERC20_PRECOMPILE_ADDRESS> with your actual data.
  curl -X POST --data '{
      "jsonrpc": "2.0",
      "method": "eth_call",
      "params": [
          {
              "to": "<WERC20_PRECOMPILE_ADDRESS>",
              "data": "0x313ce567"
          },
          "latest"
      ],
      "id": 1
  }' -H "Content-Type: application/json" <RPC_URL>
  ```
</CodeGroup>

### `increaseAllowance`

Increases the allowance granted to a spender.

### `decreaseAllowance`

Decreases the allowance granted to a spender.

## Full Solidity Interface & ABI

```solidity title="WERC20 Solidity Interface" lines expandable
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.8.18;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

/// @author The Berachain Polaris Team
/// @title WERC20 Precompile Contract
/// @dev The interface through which solidity contracts will interact with the WERC20 precompile
interface IWERC20 is IERC20 {
    /// @dev Emitted when a user deposits tokens into the contract
    /// @param dst The address of the user who deposited tokens
    /// @param wad The amount of tokens deposited
    event Deposit(address indexed dst, uint256 wad);

    /// @dev Emitted when a user withdraws tokens from the contract
    /// @param src The address of the user who withdrew tokens
    /// @param wad The amount of tokens withdrawn
    event Withdrawal(address indexed src, uint256 wad);

    /// @dev Deposits tokens into the contract
    function deposit() external payable;

    /// @dev Withdraws tokens from the contract
    /// @param wad The amount of tokens to withdraw
    function withdraw(uint256 wad) external;
}
```

```json title="WERC20 ABI" lines expandable
{
  "_format": "hh-sol-artifact-1",
  "contractName": "IWERC20",
  "sourceName": "solidity/precompiles/werc20/IWERC20.sol",
  "abi": [
    { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "owner", "type": "address" }, { "indexed": true, "internalType": "address", "name": "spender", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "value", "type": "uint256" } ], "name": "Approval", "type": "event" },
    { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "dst", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "wad", "type": "uint256" } ], "name": "Deposit", "type": "event" },
    { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "from", "type": "address" }, { "indexed": true, "internalType": "address", "name": "to", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "value", "type": "uint256" } ], "name": "Transfer", "type": "event" },
    { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "src", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "wad", "type": "uint256" } ], "name": "Withdrawal", "type": "event" },
    { "inputs": [ { "internalType": "address", "name": "owner", "type": "address" }, { "internalType": "address", "name": "spender", "type": "address" } ], "name": "allowance", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" },
    { "inputs": [ { "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "approve", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" },
    { "inputs": [ { "internalType": "address", "name": "account", "type": "address" } ], "name": "balanceOf", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" },
    { "inputs": [], "name": "deposit", "outputs": [], "stateMutability": "payable", "type": "function" },
    { "inputs": [], "name": "totalSupply", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" },
    { "inputs": [ { "internalType": "address", "name": "to", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "transfer", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" },
    { "inputs": [ { "internalType": "address", "name": "from", "type": "address" }, { "internalType": "address", "name": "to", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "transferFrom", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" },
    { "inputs": [ { "internalType": "uint256", "name": "wad", "type": "uint256" } ], "name": "withdraw", "outputs": [], "stateMutability": "nonpayable", "type": "function" }
  ]
}
```
