Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion doc/api-reference/applications-precompiles/bridge.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ The bridge precompile allows users to initiate withdrawals from Pod to Ethereum.

For how the bridge works end-to-end, see [Native Bridge](https://docs.v2.pod.network/documentation/native-bridge). For step-by-step guides, see [Bridge to Pod](../guides/bridge-to-pod.md) and [Bridge from Pod](../guides/bridge-from-pod.md).

**Precompile address:** `0x000000000000000000000000000000000000C10`
**Precompile address:** `0x0000000000000000000000000000000000B41D9E`

## Interface

Expand Down Expand Up @@ -33,3 +33,13 @@ interface IPodBridge {
) external returns (bytes32 id);
}
```

## Decimal Scaling

All tokens on Pod are represented with 18 decimals, regardless of their decimals on Ethereum (e.g. USDC has 6 decimals on Ethereum but 18 on Pod).

When calling `deposit` to bridge from Pod to Ethereum, the `amount` must be specified in the **Ethereum token's units**, not in Pod's 18-decimal representation. For example, to bridge 1 USDC, pass `1000000` (1e6), not `1000000000000000000` (1e18).

## Native Token Deposits

When depositing the native token (ETH), **`tx.value` must be `0`**. The bridge deducts the balance internally — do not send value with the transaction.
22 changes: 17 additions & 5 deletions doc/api-reference/guides/bridge-from-pod.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,22 @@

This guide walks through bridging ERC20 tokens from Pod to Ethereum. For background on how the bridge works, see [Native Bridge](https://docs.v2.pod.network/documentation/native-bridge).

## Decimal Scaling

All tokens on Pod are represented with 18 decimals, regardless of their decimals on Ethereum. When calling `deposit` on the Pod bridge precompile, the `amount` must be specified in the **Ethereum token's units**. For example, to bridge 1 USDC (6 decimals on Ethereum), pass `1000000` (1e6), not `1000000000000000000` (1e18).

{% hint style="warning" %}
When bridging the native token, **set `tx.value` to `0`**. The bridge deducts the balance internally — do not send value with the transaction.
{% endhint %}

## Steps

1. Call `deposit(token, amount, ethRecipient)` on the Pod bridge precompile.
2. Call `pod_getBridgeClaimProof(txHash)` on the full node to get the claim proof.
3. Call `claim(token, amount, ethRecipient, proof, auxTxSuffix)` on the Ethereum bridge contract.

## Examples for bridging 100 tokens (e.g. USDC) from Pod to Ethereum (assuming 6 decimals on Ethereum):

{% tabs %}
{% tab title="TypeScript (ethers.js)" %}
```typescript
Expand All @@ -18,20 +28,21 @@ const ethProvider = new ethers.JsonRpcProvider("https://eth.llamarpc.com");
const podWallet = new ethers.Wallet(PRIVATE_KEY, podProvider);
const ethWallet = new ethers.Wallet(PRIVATE_KEY, ethProvider);

const POD_BRIDGE = "0x000000000000000000000000000000000000C10";
const POD_BRIDGE = "0x0000000000000000000000000000000000B41D9E";
const ETH_BRIDGE = "ETHEREUM_BRIDGE_ADDRESS";
const POD_TOKEN = "POD_TOKEN_ADDRESS"; // use 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE for native token
const ETH_TOKEN = "ETH_TOKEN_ADDRESS";
const amount = ethers.parseUnits("100", 6);
const amount = ethers.parseUnits("100", 6); // amount in Ethereum token units (e.g. 6 decimals for USDC)
const ethRecipient = ethWallet.address;

// 1. Deposit on Pod bridge precompile
// IMPORTANT: tx.value must be 0, even for native token deposits
const podBridge = new ethers.Contract(
POD_BRIDGE,
["function deposit(address token, uint256 amount, address to) returns (bytes32)"],
podWallet
);
const depositTx = await podBridge.deposit(POD_TOKEN, amount, ethRecipient);
const depositTx = await podBridge.deposit(POD_TOKEN, amount, ethRecipient, { value: 0 });
const receipt = await depositTx.wait();

// 2. Get claim proof
Expand Down Expand Up @@ -83,12 +94,13 @@ let eth_provider = ProviderBuilder::new()

let pod_token = "POD_TOKEN_ADDRESS".parse()?; // use 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE for native token
let eth_token = "ETH_TOKEN_ADDRESS".parse()?;
let amount = U256::from(100_000_000u64); // e.g. 100 USDC
let amount = U256::from(100_000_000u64); // amount in Ethereum token units (e.g. 100 USDC = 100 * 1e6)
let eth_recipient = signer.address();

// 1. Deposit on Pod bridge precompile
// IMPORTANT: tx.value must be 0, even for native token deposits
let pod_bridge = PodBridge::new(
"0x000000000000000000000000000000000000C10".parse()?,
"0x0000000000000000000000000000000000B41D9E".parse()?,
&pod_provider,
);
let deposit_receipt = pod_bridge
Expand Down
9 changes: 8 additions & 1 deletion doc/protocol/native-bridge.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Pod has a native bridge for moving ERC20 tokens between Ethereum and Pod. The br
## Architecture

- **Ethereum bridge contract** - holds deposited tokens on Ethereum. Users deposit here to bridge into Pod, and claim here when bridging out.
- **Pod bridge precompile** - at `0x000000000000000000000000000000000000C10` on Pod. Users call this to initiate withdrawals to Ethereum.
- **Pod bridge precompile** - at `0x0000000000000000000000000000000000B41D9E` on Pod. Users call this to initiate withdrawals to Ethereum.

## Ethereum → Pod

Expand All @@ -21,6 +21,13 @@ The user obtains the claim proof via `pod_getBridgeClaimProof(txHash)` and submi

See [Bridge from Pod](https://docs.v2.pod.network/guides-references/guides/bridge-from-pod) for a step-by-step guide with code examples.

## Decimal Scaling

All tokens on Pod are represented with 18 decimals internally, regardless of their decimals on the source chain (e.g. USDC has 6 decimals on Ethereum but 18 on Pod). The bridge handles the conversion automatically:

- **Ethereum → Pod**: The bridge scales amounts up to 18 decimals when crediting balances on Pod.
- **Pod → Ethereum**: When calling `deposit` on the Pod bridge precompile, the `amount` must be specified in the Ethereum token's native units (e.g. 1e6 for 1 USDC), not in Pod's 18-decimal representation. The Deposit event also emits amounts in the source chain's decimals.

## Network Upgrades

When the network is upgraded (e.g. validator set changes), past certificates are invalidated because the signing domain changes. Claims from before the upgrade use a merkle inclusion proof instead - the admin commits a merkle root covering all pending claims from the previous version.
Expand Down