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
5 changes: 5 additions & 0 deletions .changeset/unichain-uniswap-weth.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@avaprotocol/protocols": minor
---

Add Unichain (130) Uniswap V3 (SwapRouter02 / QuoterV2 / Factory / NFT Position Manager / Permit2 / Universal Router) plus `wrapped.weth` and native Circle USDC. Addresses from the official Uniswap Unichain deployment page and Circle USDC docs.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ const sig = Protocols.aaveV3.eventTopics.Borrow;
| **Sky (sDAI)** | sDAI vault + standard ERC-4626 ABI | Mainnet |
| **Spark** | SparkLend Pool (AAVE V3 fork — reuse AAVE Pool ABI) | Mainnet |
| **Superfluid** | CFAv1Forwarder + setFlowrate/createFlow ABI | Mainnet, Base, **BNB** |
| **Uniswap V3** | SwapRouter02, QuoterV2, Permit2, Factory, NFT Position Manager, Universal Router + ABIs | Mainnet, Sepolia, **Optimism**, Base, Base Sepolia, **BNB**, **Arbitrum** |
| **Wrapped Ether** | Canonical wrapper of native gas + WETH9 ABI (WBNB on BNB) | Mainnet, Sepolia, **Optimism**, Base, Base Sepolia, **BNB**, **Arbitrum** |
| **Uniswap V3** | SwapRouter02, QuoterV2, Permit2, Factory, NFT Position Manager, Universal Router + ABIs | Mainnet, Sepolia, **Optimism**, Base, Base Sepolia, **BNB**, **Arbitrum**, **Unichain** |
| **Wrapped Ether** | Canonical wrapper of native gas + WETH9 ABI (WBNB on BNB) | Mainnet, Sepolia, **Optimism**, Base, Base Sepolia, **BNB**, **Arbitrum**, **Unichain** |
| **ERC-20** | Standard `approve` ABI fragment | n/a |

Shared ABIs (consumed by multiple protocol modules):
Expand Down
1 change: 1 addition & 0 deletions src/chains.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export const Chains = Object.freeze({
Sepolia: 11_155_111 as const,
Holesky: 17_000 as const,
OptimismMainnet: 10 as const,
UnichainMainnet: 130 as const,
BaseMainnet: 8453 as const,
BaseSepolia: 84_532 as const,
BnbMainnet: 56 as const,
Expand Down
10 changes: 10 additions & 0 deletions src/protocols/uniswap-v3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ const swapRouter02: AddressByChain = {
[Chains.BnbMainnet]: "0xB971eF87ede563556b2ED4b1C0b0019111Dd85d2",
// https://developers.uniswap.org/contracts/v3/reference/deployments/arbitrum-deployments
[Chains.ArbitrumOne]: "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",
// https://developers.uniswap.org/docs/protocols/v3/deployments/v3-unichain-deployments
[Chains.UnichainMainnet]: "0x73855d06DE49d0fe4A9c42636Ba96c62da12FF9C",
};

/** QuoterV2 — off-chain quote helper for swap previews. */
Expand All @@ -37,6 +39,7 @@ const quoterV2: AddressByChain = {
[Chains.OptimismMainnet]: "0x61fFE014bA17989E743c5F6cB21bF9697530B21e",
[Chains.BnbMainnet]: "0x78D78E420Da98ad378D7799bE8f4AF69033EB077",
[Chains.ArbitrumOne]: "0x61fFE014bA17989E743c5F6cB21bF9697530B21e",
[Chains.UnichainMainnet]: "0x385A5cf5F83e99f7BB2852b6A19C3538b9FA7658",
};

/**
Expand All @@ -51,6 +54,7 @@ const permit2: AddressByChain = {
[Chains.OptimismMainnet]: "0x000000000022d473030F116dDEE9F6B43aC78BA3",
[Chains.BnbMainnet]: "0x000000000022d473030F116dDEE9F6B43aC78BA3",
[Chains.ArbitrumOne]: "0x000000000022d473030F116dDEE9F6B43aC78BA3",
[Chains.UnichainMainnet]: "0x000000000022d473030F116dDEE9F6B43aC78BA3",
};

/** Uniswap V3 Factory — derives the deterministic pool address per token-pair+fee. */
Expand All @@ -62,6 +66,7 @@ const factory: AddressByChain = {
[Chains.OptimismMainnet]: "0x1F98431c8aD98523631AE4a59f267346ea31F984",
[Chains.BnbMainnet]: "0xdB1d10011AD0Ff90774D0C6Bb92e5C5c8b4461F7",
[Chains.ArbitrumOne]: "0x1F98431c8aD98523631AE4a59f267346ea31F984",
[Chains.UnichainMainnet]: "0x1F98400000000000000000000000000000000003",
};

/** NonfungiblePositionManager — LP NFT mint/burn/collect. */
Expand All @@ -73,6 +78,7 @@ const nonfungiblePositionManager: AddressByChain = {
[Chains.OptimismMainnet]: "0xC36442b4a4522E871399CD717aBDD847Ab11FE88",
[Chains.BnbMainnet]: "0x7b8A01B39D58278b5DE7e48c8449c9f4F5170613",
[Chains.ArbitrumOne]: "0xC36442b4a4522E871399CD717aBDD847Ab11FE88",
[Chains.UnichainMainnet]: "0x943e6e07a7E8E791dAFC44083e54041D743C46E9",
};

/** UniversalRouter — Uniswap's multi-step routing entrypoint (Permit2-aware). */
Expand All @@ -84,6 +90,7 @@ const universalRouter: AddressByChain = {
[Chains.OptimismMainnet]: "0x851116d9223fabed8e56c0e6b8ad0c31d98b3507",
[Chains.BnbMainnet]: "0x4Dae2f939ACf50408e13d58534Ff8c2776d45265",
[Chains.ArbitrumOne]: "0xa51afafe0263b40edaef0df8781ea9aa03e381a3",
[Chains.UnichainMainnet]: "0xe6039aE5B44f90d56c6B029354Fb22999861A9A0",
};

/**
Expand Down Expand Up @@ -217,6 +224,7 @@ const tokens = Object.freeze({
[Chains.OptimismMainnet]: "0x4200000000000000000000000000000000000006",
[Chains.BnbMainnet]: "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",
[Chains.ArbitrumOne]: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
[Chains.UnichainMainnet]: "0x4200000000000000000000000000000000000006",
} satisfies AddressByChain,
USDC: {
[Chains.Sepolia]: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
Expand All @@ -227,6 +235,8 @@ const tokens = Object.freeze({
[Chains.BnbMainnet]: "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",
// Native Circle USDC (not bridged USDC.e).
[Chains.ArbitrumOne]: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
// Native Circle USDC (https://developers.circle.com/stablecoins/usdc-on-unichain).
[Chains.UnichainMainnet]: "0x078D782b760474a361dDA0AF3839290b0EF57AD6",
} satisfies AddressByChain,
});

Expand Down
1 change: 1 addition & 0 deletions src/protocols/wrapped.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const weth: AddressByChain = {
[Chains.OptimismMainnet]: "0x4200000000000000000000000000000000000006",
[Chains.BnbMainnet]: "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",
[Chains.ArbitrumOne]: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
[Chains.UnichainMainnet]: "0x4200000000000000000000000000000000000006",
};

/**
Expand Down
13 changes: 13 additions & 0 deletions tests/catalog.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,18 @@ describe("Uniswap V3 catalog", () => {
expect(Protocols.uniswapV3.swapRouter02[Chains.OptimismMainnet]).toBe(
"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",
);
expect(Protocols.uniswapV3.swapRouter02[Chains.UnichainMainnet]).toBe(
"0x73855d06DE49d0fe4A9c42636Ba96c62da12FF9C",
);
expect(Protocols.uniswapV3.factory[Chains.UnichainMainnet]).toBe(
"0x1F98400000000000000000000000000000000003",
);
expect(Protocols.uniswapV3.tokens.USDC[Chains.UnichainMainnet]).toBe(
"0x078D782b760474a361dDA0AF3839290b0EF57AD6",
);
expect(Protocols.wrapped.weth[Chains.UnichainMainnet]).toBe(
"0x4200000000000000000000000000000000000006",
);
});

it("ships exactInputSingle in the SwapRouter02 ABI", () => {
Expand All @@ -339,6 +351,7 @@ describe("Uniswap V3 catalog", () => {
Chains.OptimismMainnet,
Chains.BnbMainnet,
Chains.ArbitrumOne,
Chains.UnichainMainnet,
]) {
expect(Protocols.uniswapV3.permit2[chainId]?.toLowerCase()).toBe(expected.toLowerCase());
}
Expand Down
Loading