Skip to content

Commit

Permalink
extract swap functionality to separate functions
Browse files Browse the repository at this point in the history
  • Loading branch information
thal0x committed Aug 21, 2024
1 parent 737297c commit e1eabda
Showing 1 changed file with 73 additions and 118 deletions.
191 changes: 73 additions & 118 deletions CCTPRelayer/src/CCTPRelayer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -131,66 +131,9 @@ contract CCTPRelayer is ICCTPRelayer, Initializable, UUPSUpgradeable, Ownable2St

uint256 outputAmount;
if (inputToken == address(0)) {
IERC20 token = IERC20(inputToken);

// Native Token
if (inputAmount != msg.value) revert InsufficientNativeToken();

// Get the contract's balances previous to the swap
uint256 preInputBalance = address(this).balance - inputAmount;
uint256 preOutputBalance = usdc.balanceOf(address(this));

// Call the swap router and perform the swap
(bool success,) = swapRouter.call{value: inputAmount}(swapCalldata);
if (!success) revert SwapFailed();

// Get the contract's balances after the swap
uint256 postInputBalance = address(this).balance;
uint256 postOutputBalance = usdc.balanceOf(address(this));

// Check that the contract's native token balance has increased
if (preOutputBalance >= postOutputBalance) revert InsufficientSwapOutput();
outputAmount = postOutputBalance - preOutputBalance;

// Refund the remaining ETH
uint256 dust = postInputBalance - preInputBalance;
if (dust != 0) {
(bool ethSuccess,) = msg.sender.call{value: dust}("");
if (!ethSuccess) revert ETHSendFailed();
}
outputAmount = _swapNativeAndReturnDust(inputAmount, swapCalldata);
} else {
IERC20 token = IERC20(inputToken);

// Get the contract's balances previous to the swap
uint256 preInputBalance = token.balanceOf(address(this));
uint256 preOutputBalance = usdc.balanceOf(address(this));

// Transfer input ERC20 tokens to the contract
token.transferFrom(msg.sender, address(this), inputAmount);

// Approve the swap router to spend the input tokens
token.approve(swapRouter, inputAmount);

// Call the swap router and perform the swap
(bool success,) = swapRouter.call(swapCalldata);
if (!success) revert SwapFailed();

// Get the contract's balances after the swap
uint256 postInputBalance = token.balanceOf(address(this));
uint256 postOutputBalance = usdc.balanceOf(address(this));

// Check that the contract's output token balance has increased
if (preOutputBalance >= postOutputBalance) revert InsufficientSwapOutput();
outputAmount = postOutputBalance - preOutputBalance;

// Refund the remaining amount
uint256 dust = postInputBalance - preInputBalance;
if (dust != 0) {
token.transfer(msg.sender, dust);

// Revoke Approval
token.approve(swapRouter, 0);
}
outputAmount = _swapAndReturnDust(inputToken, inputAmount, swapCalldata);
}

// Check that output amount is enough to cover the fee
Expand Down Expand Up @@ -224,66 +167,9 @@ contract CCTPRelayer is ICCTPRelayer, Initializable, UUPSUpgradeable, Ownable2St

uint256 outputAmount;
if (inputToken == address(0)) {
// Native Token
if (inputAmount != msg.value) revert InsufficientNativeToken();

IERC20 token = IERC20(inputToken);

// Get the contract's balances previous to the swap
uint256 preInputBalance = address(this).balance - inputAmount;
uint256 preOutputBalance = usdc.balanceOf(address(this));

// Call the swap router and perform the swap
(bool success,) = swapRouter.call{value: inputAmount}(swapCalldata);
if (!success) revert SwapFailed();

// Get the contract's balances after the swap
uint256 postInputBalance = address(this).balance;
uint256 postOutputBalance = usdc.balanceOf(address(this));

// Check that the contract's native token balance has increased
if (preOutputBalance >= postOutputBalance) revert InsufficientSwapOutput();
outputAmount = postOutputBalance - preOutputBalance;

// Refund the remaining ETH
uint256 dust = postInputBalance - preInputBalance;
if (dust != 0) {
(bool ethSuccess,) = msg.sender.call{value: dust}("");
if (!ethSuccess) revert ETHSendFailed();
}
outputAmount = _swapNativeAndReturnDust(inputAmount, swapCalldata);
} else {
IERC20 token = IERC20(inputToken);

// Get the contract's balances previous to the swap
uint256 preInputBalance = token.balanceOf(address(this));
uint256 preOutputBalance = usdc.balanceOf(address(this));

// Transfer input ERC20 tokens to the contract
token.transferFrom(msg.sender, address(this), inputAmount);

// Approve the swap router to spend the input tokens
token.approve(swapRouter, inputAmount);

// Call the swap router and perform the swap
(bool success,) = swapRouter.call(swapCalldata);
if (!success) revert SwapFailed();

// Get the contract's balances after the swap
uint256 postInputBalance = token.balanceOf(address(this));
uint256 postOutputBalance = usdc.balanceOf(address(this));

// Check that the contract's output token balance has increased
if (preOutputBalance >= postOutputBalance) revert InsufficientSwapOutput();
outputAmount = postOutputBalance - preOutputBalance;

// Refund the remaining amount
uint256 dust = postInputBalance - preInputBalance;
if (dust != 0) {
token.transfer(msg.sender, dust);

// Revoke Approval
token.approve(swapRouter, 0);
}
outputAmount = _swapAndReturnDust(inputToken, inputAmount, swapCalldata);
}

// Check that output amount is enough to cover the fee
Expand Down Expand Up @@ -335,4 +221,73 @@ contract CCTPRelayer is ICCTPRelayer, Initializable, UUPSUpgradeable, Ownable2St
receive() external payable {}

function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}

function _swapAndReturnDust(address inputToken, uint256 inputAmount, bytes memory swapCalldata)
internal
returns (uint256 outputAmount)
{
IERC20 token = IERC20(inputToken);

// Get the contract's balances previous to the swap
uint256 preInputBalance = token.balanceOf(address(this));
uint256 preOutputBalance = usdc.balanceOf(address(this));

// Transfer input ERC20 tokens to the contract
token.transferFrom(msg.sender, address(this), inputAmount);

// Approve the swap router to spend the input tokens
token.approve(swapRouter, inputAmount);

// Call the swap router and perform the swap
(bool success,) = swapRouter.call(swapCalldata);
if (!success) revert SwapFailed();

// Get the contract's balances after the swap
uint256 postInputBalance = token.balanceOf(address(this));
uint256 postOutputBalance = usdc.balanceOf(address(this));

// Check that the contract's output token balance has increased
if (preOutputBalance >= postOutputBalance) revert InsufficientSwapOutput();
outputAmount = postOutputBalance - preOutputBalance;

// Refund the remaining amount
uint256 dust = postInputBalance - preInputBalance;
if (dust != 0) {
token.transfer(msg.sender, dust);

// Revoke Approval
token.approve(swapRouter, 0);
}
}

function _swapNativeAndReturnDust(uint256 inputAmount, bytes memory swapCalldata)
internal
returns (uint256 outputAmount)
{
// Native Token
if (inputAmount != msg.value) revert InsufficientNativeToken();

// Get the contract's balances previous to the swap
uint256 preInputBalance = address(this).balance - inputAmount;
uint256 preOutputBalance = usdc.balanceOf(address(this));

// Call the swap router and perform the swap
(bool success,) = swapRouter.call{value: inputAmount}(swapCalldata);
if (!success) revert SwapFailed();

// Get the contract's balances after the swap
uint256 postInputBalance = address(this).balance;
uint256 postOutputBalance = usdc.balanceOf(address(this));

// Check that the contract's native token balance has increased
if (preOutputBalance >= postOutputBalance) revert InsufficientSwapOutput();
outputAmount = postOutputBalance - preOutputBalance;

// Refund the remaining ETH
uint256 dust = postInputBalance - preInputBalance;
if (dust != 0) {
(bool ethSuccess,) = msg.sender.call{value: dust}("");
if (!ethSuccess) revert ETHSendFailed();
}
}
}

0 comments on commit e1eabda

Please sign in to comment.