Skip to content

Commit 64d877d

Browse files
authored
Refactor the Swap example to swap arbitrary ERC-20 and swap from EVM to Bitcoin (#85)
1 parent fa8c2b6 commit 64d877d

File tree

6 files changed

+1158
-707
lines changed

6 files changed

+1158
-707
lines changed

omnichain/swap/contracts/Swap.sol

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -30,47 +30,42 @@ contract Swap is zContract {
3030
uint256 amount,
3131
bytes calldata message
3232
) external virtual override onlySystem {
33-
uint32 targetChainID;
34-
address recipient;
35-
uint256 minAmountOut;
33+
address targetTokenAddress;
34+
bytes memory recipientAddress;
3635

3736
if (context.chainID == BITCOIN) {
38-
targetChainID = BytesHelperLib.bytesToUint32(message, 0);
39-
recipient = BytesHelperLib.bytesToAddress(message, 4);
37+
targetTokenAddress = BytesHelperLib.bytesToAddress(message, 0);
38+
recipientAddress = abi.encodePacked(
39+
BytesHelperLib.bytesToAddress(message, 20)
40+
);
4041
} else {
41-
(
42-
uint32 targetChainID_,
43-
address recipient_,
44-
uint256 minAmountOut_
45-
) = abi.decode(message, (uint32, address, uint256));
46-
targetChainID = targetChainID_;
47-
recipient = recipient_;
48-
minAmountOut = minAmountOut_;
42+
(address targetToken, bytes memory recipient) = abi.decode(
43+
message,
44+
(address, bytes)
45+
);
46+
targetTokenAddress = targetToken;
47+
recipientAddress = recipient;
4948
}
5049

51-
address targetZRC20 = systemContract.gasCoinZRC20ByChainId(
52-
targetChainID
53-
);
54-
5550
uint256 outputAmount = SwapHelperLib._doSwap(
5651
systemContract.wZetaContractAddress(),
5752
systemContract.uniswapv2FactoryAddress(),
5853
systemContract.uniswapv2Router02Address(),
5954
zrc20,
6055
amount,
61-
targetZRC20,
62-
minAmountOut
56+
targetTokenAddress,
57+
0
6358
);
6459

65-
(address gasZRC20, uint256 gasFee) = IZRC20(targetZRC20)
60+
(address gasZRC20, uint256 gasFee) = IZRC20(targetTokenAddress)
6661
.withdrawGasFee();
6762

68-
if (gasZRC20 != targetZRC20) revert WrongGasContract();
63+
if (gasZRC20 != targetTokenAddress) revert WrongGasContract();
6964
if (gasFee >= outputAmount) revert NotEnoughToPayGasFee();
7065

71-
IZRC20(targetZRC20).approve(targetZRC20, gasFee);
72-
IZRC20(targetZRC20).withdraw(
73-
abi.encodePacked(recipient),
66+
IZRC20(targetTokenAddress).approve(targetTokenAddress, gasFee);
67+
IZRC20(targetTokenAddress).withdraw(
68+
recipientAddress,
7469
outputAmount - gasFee
7570
);
7671
}

omnichain/swap/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"@types/node": ">=12.0.0",
2727
"@typescript-eslint/eslint-plugin": "^5.59.9",
2828
"@typescript-eslint/parser": "^5.59.9",
29-
"@zetachain/toolkit": "^3.0.0",
29+
"@zetachain/toolkit": "^4.0.0",
3030
"axios": "^1.3.6",
3131
"chai": "^4.2.0",
3232
"dotenv": "^16.0.3",
@@ -48,4 +48,4 @@
4848
"typechain": "^8.1.0",
4949
"typescript": ">=4.5.0"
5050
}
51-
}
51+
}

omnichain/swap/tasks/deploy.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,7 @@ const main = async (args: any, hre: HardhatRuntimeEnvironment) => {
3434
}
3535
};
3636

37-
task("deploy", "Deploy the contract", main).addFlag("json", "Output in JSON");
37+
task("deploy", "Deploy the contract", main).addFlag(
38+
"json",
39+
"Output in JSON"
40+
);

omnichain/swap/tasks/interact.ts

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,28 @@ import { HardhatRuntimeEnvironment } from "hardhat/types";
33
import { parseEther } from "@ethersproject/units";
44
import { getAddress } from "@zetachain/protocol-contracts";
55
import { prepareData } from "@zetachain/toolkit/helpers";
6-
import { BigNumber } from "@ethersproject/bignumber";
6+
import bech32 from "bech32";
7+
import { utils } from "ethers";
78

89
const main = async (args: any, hre: HardhatRuntimeEnvironment) => {
910
const [signer] = await hre.ethers.getSigners();
1011

11-
const targetChainID = hre.config.networks[args.destination]?.chainId;
12-
if (targetChainID === undefined) {
13-
throw new Error("Invalid destination network");
12+
let recipient;
13+
try {
14+
if (bech32.decode(args.recipient)) {
15+
recipient = utils.solidityPack(
16+
["bytes"],
17+
[utils.toUtf8Bytes(args.recipient)]
18+
);
19+
}
20+
} catch (e) {
21+
recipient = args.recipient;
1422
}
15-
const minAmountOut = BigNumber.from("0");
1623

1724
const data = prepareData(
1825
args.contract,
19-
["uint32", "address", "uint256"],
20-
[targetChainID, args.recipient, minAmountOut]
26+
["address", "bytes"],
27+
[args.targetToken, recipient]
2128
);
2229
const to = getAddress("tss", hre.network.name);
2330
const value = parseEther(args.amount);
@@ -30,14 +37,14 @@ const main = async (args: any, hre: HardhatRuntimeEnvironment) => {
3037
console.log(`🔑 Using account: ${signer.address}\n`);
3138

3239
console.log(`🚀 Successfully broadcasted a token transfer transaction on ${hre.network.name} network.
33-
📝 Transaction hash: ${tx.hash}
34-
`);
40+
📝 Transaction hash: ${tx.hash}
41+
`);
3542
}
3643
};
3744

3845
task("interact", "Interact with the contract", main)
3946
.addParam("contract", "The address of the withdraw contract on ZetaChain")
4047
.addParam("amount", "Amount of tokens to send")
41-
.addParam("recipient")
4248
.addFlag("json", "Output in JSON")
43-
.addParam("destination");
49+
.addParam("targetToken")
50+
.addParam("recipient");

0 commit comments

Comments
 (0)