Compare commits

...

17 Commits

Author SHA1 Message Date
Karl Kempe 1b22be73f1 Fix links 2022-01-31 23:03:23 +00:00
Karl Kempe 2fe1b50a61 Remove configs 2022-01-31 22:59:34 +00:00
Karl Kempe e40f29ad28 Update README 2022-01-31 22:58:05 +00:00
Karl Kempe 20cff589b0 Resolve merge conflict 2022-01-31 22:51:14 +00:00
Karl Kempe 0c77f095a1 Modify .env.sample 2022-01-31 22:49:13 +00:00
Karl Kempe 9ad1a75ccb Fix test qty 2022-01-31 22:48:46 +00:00
Karl Kempe fe5fa89201 Add more faucet links 2022-01-31 22:47:12 +00:00
Karl Kempe 3b41ec9ae2 Update README; add avax and bsc rpc 2022-01-31 22:42:18 +00:00
Karl Kempe 3b6e8963e7 Update gas parameters 2022-01-31 22:08:11 +00:00
Kevin Peters 73e9c8cf42 UI - fixed some typescript errors 2022-01-31 20:14:57 +00:00
Karl Kempe 3155cb88b9 Fix swap-with-vaa; add swap-everything 2022-01-31 19:59:39 +00:00
Karl Kempe d059b46e85 Fix icon handling 2022-01-31 19:58:45 +00:00
Drew Sterioti 49916d6f4c Add BSC/AVAX testnet providers to .env.sample 2022-01-26 16:05:48 +00:00
Drew Sterioti a5c0e1d0b2 Add AVAX/BSC truffle cfgs 2022-01-26 16:00:44 +00:00
Drew Sterioti 65caca3c16 Merge branch 'cross-chain-swap' of github.com:certusone/wormhole-nativeswap-example into cross-chain-swap 2022-01-26 15:58:57 +00:00
Drew Sterioti 466c1a3abd Merge branch 'cross-chain-swap' of github.com:certusone/wormhole-nativeswap-example into cross-chain-swap 2022-01-23 21:46:51 +00:00
Drew Sterioti 6e3e5758b8 Merge branch 'cross-chain-swap' of github.com:certusone/wormhole-nativeswap-example into cross-chain-swap 2022-01-23 21:35:04 +00:00
10 changed files with 157 additions and 42 deletions

View File

@ -1,12 +1,14 @@
## NativeSwap
https://certusone.github.io/wormhole-nativeswap-example/
This is a non-production example program.
Multi-chain native-to-native token swap using existing DEXes.
### Details
Using liquidity of native vs UST (i.e. the UST highway), one can swap from native A on chain A to native B on chain B. For this specific example, we demonstrate a swap between Polygon (Mumbai testnet) and Ethereum (Goerli testnet) between MATIC and ETH. We wrote example smart contracts to interact with Uniswap V3 and Uniswap V2 forks (QuickSwap in this specific example for Polygon). Any DEX can be used to replace our example as long as the swap for a particular DEX has all of its parameters to perform the swap(s).
Using liquidity of native vs UST (i.e. the UST highway), one can swap from native A on chain A to native B on chain B. For this specific example, we demonstrate a swap between any combination of ETH (Goerli testnet), AVAX (Fuji testnet), MATIC (Mumbai testnet) and BNB (BSC testnet). We wrote example smart contracts to interact with Uniswap V3 and Uniswap V2 forks. Any DEX can be used to replace our example as long as the swap for a particular DEX has all of its parameters to perform the swap(s).
A protocol that hosts NativeSwap is expected to run its own relayer to enhance its user experience by only requiring a one-click transaction to perform the complete swap. Otherwise the user will have to perform an extra transaction to manually allow the final swap.
@ -49,8 +51,8 @@ cp .env.sample .env
Then deploy the example contracts:
```
./deploy_to_goerli.sh
./deploy_to_mumbai.sh
./deploy_v2.sh
./deploy_v3.sh
```
Then change into the react directory, copy sample.env to .env and replace YOUR-PROJECT-ID with your Infura Goerli and Mumbai Project IDs

View File

@ -1,3 +1,5 @@
GOERLI_PROVIDER=https://goerli.infura.io/v3/YOUR-PROJECT-ID
MUMBAI_PROVIDER=https://polygon-mumbai.infura.io/v3/YOUR-PROJECT-ID
ETH_PRIVATE_KEY=
GOERLI_PROVIDER="https://goerli.infura.io/v3/YOUR-PROJECT-ID"
MUMBAI_PROVIDER="https://polygon-mumbai.infura.io/v3/YOUR-PROJECT-ID"
BSC_PROVIDER="https://data-seed-prebsc-1-s1.binance.org:8545"
FUJI_PROVIDER="https://api.avax-test.network/ext/bc/C/rpc"
ETH_PRIVATE_KEY=

View File

@ -0,0 +1,17 @@
#!/bin/bash
set -euo pipefail
root=$(dirname $0)
script="${root}/swap-with-vaa.js"
echo `which node`
node $script --in ETH --out MATIC
node $script --in ETH --out BNB
node $script --in ETH --out AVAX
node $script --in MATIC --out BNB
node $script --in MATIC --out AVAX
node $script --in BNB --out MATIC
echo "done"

View File

@ -1,3 +1,4 @@
import yargs from "yargs";
import { ethers } from "ethers";
import { NodeHttpTransport } from "@improbable-eng/grpc-web-node-http-transport";
@ -24,7 +25,7 @@ require("dotenv").config({ path: ".env" });
const SWAP_AMOUNT_IN_MATIC = "0.0069";
const SWAP_AMOUNT_IN_ETH = "0.000907";
const SWAP_AMOUNT_IN_AVAX = "0.0075";
const SWAP_AMOUNT_IN_BNB = "0.015";
const SWAP_AMOUNT_IN_BNB = "0.0015";
const SWAP_AMOUNT_IN_UST = "3.40";
const SWAP_DEADLINE = "1800";
@ -33,6 +34,34 @@ const SWAP_SLIPPAGE = "0.01";
// token bridge things
const BRIDGE_RELAYER_FEE_UST = "0.25";
interface Arguments {
in: string;
out: string;
}
function parseArgs(): Arguments {
const parsed = yargs(process.argv.slice(2))
.option("in", {
string: true,
description: "Name of inbound token",
required: true,
})
.option("out", {
string: true,
description: "Name of outbound token",
required: true,
})
.help("h")
.alias("h", "help").argv;
const args: Arguments = {
in: parsed.in,
out: parsed.out,
};
return args;
}
export function makeEvmWallet(
provider: ethers.providers.Provider
): ethers.Wallet {
@ -347,19 +376,44 @@ async function swapEverythingExactOut(
return;
}
function getTokenInfo(name: string) {
switch (name) {
case "ETH": {
return ETH_TOKEN_INFO;
}
case "MATIC": {
return MATIC_TOKEN_INFO;
}
case "UST": {
return UST_TOKEN_INFO;
}
case "AVAX": {
return AVAX_TOKEN_INFO;
}
case "BNB": {
return BNB_TOKEN_INFO;
}
default: {
throw Error("invalid token name");
}
}
}
async function main() {
const args = parseArgs();
const testExactIn = true;
const isNative = true;
const swapper = new UniswapToUniswapExecutor();
swapper.setTransport(NodeHttpTransport());
const tokenIn = ETH_TOKEN_INFO;
//const tokenOut = MATIC_TOKEN_INFO;
const tokenOut = UST_TOKEN_INFO;
const tokenIn = getTokenInfo(args.in);
const tokenOut = getTokenInfo(args.out);
//const tokenOut = UST_TOKEN_INFO;
//const recipientAddress = "0x4e2dfAD7D7d0076b5A0A41223E4Bee390C33251C";
const recipientAddress = "terra1vewnsxcy5fqjslyyy409cw8js550esen38n8ey";
const recipientAddress = "0x4e2dfAD7D7d0076b5A0A41223E4Bee390C33251C";
//const recipientAddress = "terra1vewnsxcy5fqjslyyy409cw8js550esen38n8ey";
if (testExactIn) {
console.info(`testing exact in. native=${isNative}`);

View File

@ -1,4 +1,4 @@
REACT_APP_GOERLI_PROVIDER=https://goerli.infura.io/v3/YOUR-PROJECT-ID
REACT_APP_MUMBAI_PROVIDER=https://polygon-mumbai.infura.io/v3/YOUR-PROJECT-ID
REACT_APP_FUJI_PROVIDER=
REACT_APP_BSC_PROVIDER=
REACT_APP_GOERLI_PROVIDER="https://goerli.infura.io/v3/YOUR-PROJECT-ID"
REACT_APP_MUMBAI_PROVIDER="https://polygon-mumbai.infura.io/v3/YOUR-PROJECT-ID"
REACT_APP_FUJI_PROVIDER="https://api.avax-test.network/ext/bc/C/rpc"
REACT_APP_BSC_PROVIDER="https://data-seed-prebsc-1-s1.binance.org:8545"

View File

@ -5,7 +5,20 @@ import {
MenuItem,
TextField,
} from "@material-ui/core";
import { TokenInfo } from "../utils/consts";
import {
AVAX_TOKEN_INFO,
BNB_TOKEN_INFO,
ETH_TOKEN_INFO,
MATIC_TOKEN_INFO,
TokenInfo,
UST_TOKEN_INFO,
} from "../utils/consts";
import ethIcon from "../icons/eth.svg";
import polygonIcon from "../icons/polygon.svg";
import terraIcon from "../icons/terra.svg";
import bscIcon from "../icons/bsc.svg";
import avaxIcon from "../icons/avax.svg";
const useStyles = makeStyles((theme) => ({
select: {
@ -23,10 +36,27 @@ const useStyles = makeStyles((theme) => ({
},
}));
const createTokenMenuItem = ({ name, logo }: TokenInfo, classes: any) => (
const getLogo = (name: string) => {
switch (name) {
case ETH_TOKEN_INFO.name:
return ethIcon;
case MATIC_TOKEN_INFO.name:
return polygonIcon;
case UST_TOKEN_INFO.name:
return terraIcon;
case AVAX_TOKEN_INFO.name:
return avaxIcon;
case BNB_TOKEN_INFO.name:
return bscIcon;
default:
return "";
}
};
const createTokenMenuItem = ({ name }: TokenInfo, classes: any) => (
<MenuItem key={name} value={name}>
<ListItemIcon className={classes.listItemIcon}>
<img src={logo} alt={name} className={classes.icon} />
<img src={getLogo(name)} alt={name} className={classes.icon} />
</ListItemIcon>
<ListItemText>{name}</ListItemText>
</MenuItem>

View File

@ -11,14 +11,14 @@ import {
export const CROSSCHAINSWAP_GAS_PARAMETERS_EIP1559 = {
gasLimit: "694200",
//maxFeePerGas: "250000000000",
maxFeePerGas: "25420690000",
maxFeePerGas: "100420690000",
maxPriorityFeePerGas: "1690000000",
};
export const CROSSCHAINSWAP_GAS_PARAMETERS_EVM = {
gasLimit: "694200",
//gasPrice: "250000000000",
gasPrice: "25420690000",
gasPrice: "20420690000",
};
export const EVM_EIP1559_CHAIN_IDS = [

View File

@ -7,12 +7,6 @@ import {
CHAIN_ID_BSC,
} from "@certusone/wormhole-sdk";
import ethIcon from "../icons/eth.svg";
import polygonIcon from "../icons/polygon.svg";
import terraIcon from "../icons/terra.svg";
import bscIcon from "../icons/bsc.svg";
import avaxIcon from "../icons/avax.svg";
export const EVM_POLYGON_NETWORK_CHAIN_ID = 80001;
export const EVM_ETH_NETWORK_CHAIN_ID = 5;
export const EVM_AVAX_NETWORK_CHAIN_ID = 43113;
@ -23,7 +17,6 @@ export interface TokenInfo {
address: string;
chainId: ChainId;
evmChainId: number | undefined;
logo: string;
maxAmount: number;
ustPairedAddress: string | undefined;
}
@ -33,7 +26,7 @@ export const MATIC_TOKEN_INFO: TokenInfo = {
address: "0x9c3c9283d3e44854697cd22d3faa240cfb032889",
chainId: CHAIN_ID_POLYGON,
evmChainId: EVM_POLYGON_NETWORK_CHAIN_ID,
logo: polygonIcon,
//logo: polygonIcon,
maxAmount: 0.1,
ustPairedAddress: "0xe3a1c77e952b57b5883f6c906fc706fcc7d4392c",
};
@ -43,7 +36,7 @@ export const ETH_TOKEN_INFO: TokenInfo = {
address: "0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6",
chainId: CHAIN_ID_ETH,
evmChainId: EVM_ETH_NETWORK_CHAIN_ID,
logo: ethIcon,
//logo: ethIcon,
maxAmount: 0.01,
ustPairedAddress: "0x36Ed51Afc79619b299b238898E72ce482600568a",
};
@ -53,7 +46,7 @@ export const AVAX_TOKEN_INFO: TokenInfo = {
address: "0x1d308089a2d1ced3f1ce36b1fcaf815b07217be3",
chainId: CHAIN_ID_AVAX,
evmChainId: EVM_AVAX_NETWORK_CHAIN_ID,
logo: avaxIcon,
//logo: avaxIcon,
maxAmount: 0.01,
ustPairedAddress: "0xe09ed38e5cd1014444846f62376ac88c5232cde9",
};
@ -63,7 +56,7 @@ export const BNB_TOKEN_INFO: TokenInfo = {
address: "0xae13d989dac2f0debff460ac112a837c89baa7cd",
chainId: CHAIN_ID_BSC,
evmChainId: EVM_BSC_NETWORK_CHAIN_ID,
logo: bscIcon,
//logo: bscIcon,
maxAmount: 0.01,
ustPairedAddress: "0x7b8eae1e85c8b189ee653d3f78733f4f788bb2c1",
};
@ -73,7 +66,7 @@ export const UST_TOKEN_INFO: TokenInfo = {
address: "uusd",
chainId: CHAIN_ID_TERRA,
evmChainId: undefined,
logo: terraIcon,
//logo: terraIcon,
maxAmount: 10.0,
ustPairedAddress: undefined,
};

View File

@ -576,22 +576,39 @@ export default function Home() {
<Typography variant="subtitle1">{relayerTimeoutString}</Typography>
)}
<Typography variant="subtitle2" color="error">
WARNING: this is a Testnet release only
WARNING: this is a testnet release only
</Typography>
</Paper>
<div className={classes.spacer} />
<Footer />
<Link href="https://goerli-faucet.slock.it/" style={{ margin: "5px" }}>
Goerli faucet
<Link href="https://goerli-faucet.slock.it/"
target="_blank" style={{ margin: "5px" }}>
Goerli Faucet
</Link>
<Link
href="https://faucet.polygon.technology/"
target="_blank"
style={{ margin: "5px" }}
>
Mumbai faucet
Mumbai Faucet
</Link>
<Link
href="https://faucet.avax-test.network/"
target="_blank"
style={{ margin: "5px" }}
>
Fuji Faucet
</Link>
<Link
href="https://testnet.binance.org/faucet-smart/"
target="_blank"
style={{ margin: "5px" }}
>
BSC Faucet
</Link>
<Link
href="https://github.com/certusone/wormhole-nativeswap-example/"
target="_blank"
style={{ margin: "5px" }}
>
NativeSwap GitHub

View File

@ -5,22 +5,22 @@ SPY_SERVICE_HOST=localhost:7073
EVM_CHAINS=ETH,BSC,POLYGON,AVAX
ETH_PROVIDER=https://goerli.infura.io/v3/your_project_id
ETH_PROVIDER=https://goerli.infura.io/v3/YOUR_PROJECT_ID
ETH_TOKEN_BRIDGE_ADDRESS=0xF890982f9310df57d00f659cf4fd87e65adEd8d7
ETH_CHAIN_ID=2
ETH_ABI=V3
BSC_PROVIDER=
BSC_PROVIDER="https://data-seed-prebsc-1-s1.binance.org:8545"
BSC_TOKEN_BRIDGE_ADDRESS=0x9dcF9D205C9De35334D646BeE44b2D2859712A09
BSC_CHAIN_ID=4
BSC_ABI=V2
POLYGON_PROVIDER=https://polygon-mumbai.infura.io/v3/your_project_id
POLYGON_PROVIDER=https://polygon-mumbai.infura.io/v3/YOUR_PROJECT_ID
POLYGON_TOKEN_BRIDGE_ADDRESS=0x377D55a7928c046E18eEbb61977e714d2a76472a
POLYGON_CHAIN_ID=5
POLYGON_ABI=V2
AVAX_PROVIDER=
AVAX_PROVIDER="https://api.avax-test.network/ext/bc/C/rpc"
AVAX_TOKEN_BRIDGE_ADDRESS=0x61E44E506Ca5659E6c0bba9b678586fA2d729756
AVAX_CHAIN_ID=6
AVAX_ABI=V2
@ -41,4 +41,4 @@ ETH_CONTRACT_ADDRESS=0x9e7Cae3a46ED297b0a05FCEeb41160fC5218E14f
BSC_CONTRACT_ADDRESS=0x0DC183c2eFAA5e1749B85f13621F5cC6aCcDa786
POLYGON_CONTRACT_ADDRESS=0x72F2F646dC979a9fA8aA685B8a47b7afe2fE0516
TERRA_CONTRACT_ADDRESS=terra163shc8unyqrndgcldaj2q9kgnqs82v0kgkhynf
AVAX_CONTRACT_ADDRESS=0x52D8A50AF35b0760335F29a4D6aaF0604B7D7484
AVAX_CONTRACT_ADDRESS=0x52D8A50AF35b0760335F29a4D6aaF0604B7D7484