Skip to content

Commit

Permalink
Swap to any
Browse files Browse the repository at this point in the history
  • Loading branch information
fadeev committed Nov 22, 2024
1 parent acd8da7 commit f425a77
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 61 deletions.
18 changes: 8 additions & 10 deletions examples/swap/contracts/Swap.sol
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,14 @@ contract Swap is UniversalContract {
context.revertMessage,
(address, address)
);
uint256 out = handleGasAndSwap(context.asset, context.amount, zrc20);
uint256 outputAmount = handleGasAndSwap(
context.asset,
context.amount,
zrc20
);
gateway.withdraw(
abi.encodePacked(sender),
out,
outputAmount,
zrc20,
RevertOptions({
revertAddress: sender,
Expand All @@ -134,13 +138,7 @@ contract Swap is UniversalContract {
);
}

// // Fallback function that reverts
// fallback() external payable {
// revert("Fallback function triggered");
// }
fallback() external payable {}

// // Receive function that reverts (for ETH transfers)
// receive() external payable {
// revert("ETH transfers not allowed");
// }
receive() external payable {}
}
139 changes: 92 additions & 47 deletions examples/swap/contracts/SwapToAnyToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -69,42 +69,64 @@ contract SwapToAnyToken is UniversalContract {
params.withdraw = withdrawFlag;
}

swapAndWithdraw(
zrc20,
amount,
params.target,
params.to,
params.withdraw
);
(
uint256 outputAmount,
address gasZRC20,
uint256 gasFee
) = handleGasAndSwap(zrc20, amount, params.target);
withdraw(params, context.sender, gasFee, gasZRC20, outputAmount, zrc20);
}

function swapAndWithdraw(
function swap(
address inputToken,
uint256 amount,
address targetToken,
bytes memory recipient,
bool withdraw
) internal {
bool withdrawFlag
) public {
IZRC20(inputToken).transferFrom(msg.sender, address(this), amount);
(
uint256 outputAmount,
address gasZRC20,
uint256 gasFee
) = handleGasAndSwap(inputToken, amount, targetToken);
withdraw(
Params({
target: targetToken,
to: recipient,
withdraw: withdrawFlag
}),
msg.sender,
gasFee,
gasZRC20,
outputAmount,
inputToken
);
}

function handleGasAndSwap(
address inputToken,
uint256 amount,
address targetToken
) internal returns (uint256, address, uint256) {
uint256 inputForGas;
address gasZRC20;
uint256 gasFee;
uint256 swapAmount = amount;
uint256 swapAmount;

if (withdraw) {
(gasZRC20, gasFee) = IZRC20(targetToken).withdrawGasFee();
(gasZRC20, gasFee) = IZRC20(targetToken).withdrawGasFee();

if (gasZRC20 == inputToken) {
swapAmount = amount - gasFee;
} else {
inputForGas = SwapHelperLib.swapTokensForExactTokens(
uniswapRouter,
inputToken,
gasFee,
gasZRC20,
amount
);
swapAmount = amount - inputForGas;
}
if (gasZRC20 == inputToken) {
swapAmount = amount - gasFee;
} else {
inputForGas = SwapHelperLib.swapTokensForExactTokens(
uniswapRouter,
inputToken,
gasFee,
gasZRC20,
amount
);
swapAmount = amount - inputForGas;
}

uint256 outputAmount = SwapHelperLib.swapExactTokensForTokens(
Expand All @@ -114,50 +136,73 @@ contract SwapToAnyToken is UniversalContract {
targetToken,
0
);
return (outputAmount, gasZRC20, gasFee);
}

if (withdraw) {
if (gasZRC20 == targetToken) {
function withdraw(
Params memory params,
address sender,
uint256 gasFee,
address gasZRC20,
uint256 outputAmount,
address inputToken
) public {
if (params.withdraw) {
if (gasZRC20 == params.target) {
IZRC20(gasZRC20).approve(
address(gateway),

Check failure

Code scanning / Slither

Unchecked transfer High

outputAmount + gasFee
);
} else {
IZRC20(gasZRC20).approve(address(gateway), gasFee);
IZRC20(targetToken).approve(address(gateway), outputAmount);
IZRC20(params.target).approve(address(gateway), outputAmount);
}
gateway.withdraw(
recipient,
abi.encodePacked(params.to),
outputAmount,
targetToken,
params.target,
RevertOptions({
revertAddress: address(0),
callOnRevert: false,
revertAddress: address(this),
callOnRevert: true,
abortAddress: address(0),
revertMessage: "",
revertMessage: abi.encode(sender, inputToken),
onRevertGasLimit: 0
})
);
} else {
IWETH9(targetToken).transfer(
address(uint160(bytes20(recipient))),
IWETH9(params.target).transfer(
address(uint160(bytes20(params.to))),
outputAmount
);
}
}

function swap(
address inputToken,
uint256 amount,
address targetToken,
bytes memory recipient,
bool withdraw
) public {
IZRC20(inputToken).transferFrom(msg.sender, address(this), amount);
function onRevert(RevertContext calldata context) external onlyGateway {
(address sender, address zrc20) = abi.decode(
context.revertMessage,
(address, address)
);
(uint256 outputAmount, , ) = handleGasAndSwap(
context.asset,
context.amount,
zrc20
);

swapAndWithdraw(inputToken, amount, targetToken, recipient, withdraw);
gateway.withdraw(
abi.encodePacked(sender),
outputAmount,
zrc20,
RevertOptions({
revertAddress: sender,
callOnRevert: false,
abortAddress: address(0),
revertMessage: "",
onRevertGasLimit: 0
})
);
}

function onRevert(
RevertContext calldata revertContext
) external onlyGateway {}
fallback() external payable {}

receive() external payable {}
}
53 changes: 49 additions & 4 deletions examples/swap/scripts/localnet.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,64 @@ npx hardhat compile --force --quiet

ZRC20_ETHEREUM=$(jq -r '.addresses[] | select(.type=="ZRC-20 ETH on 5") | .address' localnet.json)
ZRC20_USDC=$(jq -r '.addresses[] | select(.type=="ZRC-20 USDC on 97") | .address' localnet.json)
ZRC20_BNB=$(jq -r '.addresses[] | select(.type=="ZRC-20 BNB on 97") | .address' localnet.json)
GATEWAY_ETHEREUM=$(jq -r '.addresses[] | select(.type=="gatewayEVM" and .chain=="ethereum") | .address' localnet.json)
GATEWAY_ZETACHAIN=$(jq -r '.addresses[] | select(.type=="gatewayZEVM" and .chain=="zetachain") | .address' localnet.json)
UNISWAP_ROUTER=$(jq -r '.addresses[] | select(.type=="uniswapRouterInstance" and .chain=="zetachain") | .address' localnet.json)
SENDER=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266

CONTRACT_ZETACHAIN=$(npx hardhat deploy --name Swap --network localhost --gateway "$GATEWAY_ZETACHAIN" --uniswap-router "$UNISWAP_ROUTER" --json | jq -r '.contractAddress')
echo -e "\n🚀 Deployed contract on ZetaChain: $CONTRACT_ZETACHAIN"
CONTRACT_SWAP=$(npx hardhat deploy --name Swap --network localhost --gateway "$GATEWAY_ZETACHAIN" --uniswap-router "$UNISWAP_ROUTER" --json | jq -r '.contractAddress')
echo -e "\n🚀 Deployed Swap contract on ZetaChain: $CONTRACT_SWAP"

CONTRACT_SWAPTOANY=$(npx hardhat deploy --name SwapToAnyToken --network localhost --gateway "$GATEWAY_ZETACHAIN" --uniswap-router "$UNISWAP_ROUTER" --json | jq -r '.contractAddress')
echo -e "\n🚀 Deployed SwapToAny contract on ZetaChain: $CONTRACT_SWAPTOANY"

npx hardhat swap-from-evm \
--network localhost \
--receiver "$CONTRACT_SWAP" \
--amount 1 \
--target "$ZRC20_BNB" \
--recipient "$SENDER"

npx hardhat localnet-check

npx hardhat swap-from-evm \
--network localhost \
--receiver "$CONTRACT_SWAP" \
--amount 1 \
--target "$ZRC20_BNB" \
--recipient "$SENDER" \
--withdraw false

npx hardhat localnet-check

npx hardhat swap-from-evm \
--network localhost \
--receiver "$CONTRACT_ZETACHAIN" \
--receiver "$CONTRACT_SWAPTOANY" \
--amount 1 \
--target "$ZRC20_USDC" \
--target "$ZRC20_BNB" \
--recipient "$SENDER"

npx hardhat localnet-check

npx hardhat swap-from-evm \
--network localhost \
--receiver "$CONTRACT_SWAPTOANY" \
--amount 1 \
--target "$ZRC20_BNB" \
--recipient "$SENDER" \
--withdraw false

npx hardhat localnet-check

npx hardhat swap-from-zetachain \
--network localhost \
--contract "$CONTRACT_SWAPTOANY" \
--amount 1 \
--zrc20 "$ZRC20_BNB" \
--target "$ZRC20_ETHEREUM" \
--recipient "$SENDER"

npx hardhat localnet-check

if [ "$1" = "start" ]; then npx hardhat localnet-stop; fi

0 comments on commit f425a77

Please sign in to comment.