Skip to content

Commit

Permalink
Single hop swap
Browse files Browse the repository at this point in the history
  • Loading branch information
gasper committed Jan 25, 2022
1 parent ab2253f commit 81d0225
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 0 deletions.
67 changes: 67 additions & 0 deletions contracts/SingleHopSwap.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
pragma solidity 0.8.11;

// Efficient single hop swap without relying on UniswapV2Lib

import "@rari-capital/solmate/src/utils/SafeTransferLib.sol";

interface IUniswapV2Pair {
function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
}

contract Swapper {

using SafeTransferLib for ERC20;

address public immutable factory;

constructor(address _factory) {
factory = _factory;
}

function swap(
address tokenIn,
address tokenOut,
uint256 amountIn,
uint256 amountOutMin
) external returns (uint256 outAmount) {

address pair = _pairFor(tokenIn, tokenOut);

ERC20(tokenIn).safeTransfer(pair, amountIn);

(uint256 reserve0, uint256 reserve1, ) = IUniswapV2Pair(pair).getReserves();

if (tokenIn < tokenOut) {
outAmount = _getAmountOut(amountIn, reserve0, reserve1);
IUniswapV2Pair(pair).swap(0, outAmount, address(this), "");
} else {
outAmount = _getAmountOut(amountIn, reserve1, reserve0);
IUniswapV2Pair(pair).swap(outAmount, 0, address(this), "");
}

require(outAmount > amountOutMin);
}

function _getAmountOut(
uint256 amountIn,
uint256 reserveIn,
uint256 reserveOut
) internal pure returns (uint256) {
uint256 amountInWithFee = amountIn * 997;
uint256 numerator = amountInWithFee * reserveOut;
uint256 denominator = reserveIn * 1000 + amountInWithFee;
return numerator / denominator;
}

function _pairFor(address tokenA, address tokenB) internal view returns (address) {
(address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
return address(uint160(uint256(keccak256(abi.encodePacked(
hex'ff',
factory,
keccak256(abi.encodePacked(token0, token1)),
hex'e18a34eb0e04b04f7a0ac29a6e80748dca96319b42c54d679cb821dca90c6303'
)))));
}

}
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,5 +86,8 @@
"ts-node": "^10.4.0",
"typechain": "^6.1.0",
"typescript": "^4.5.0"
},
"dependencies": {
"@rari-capital/solmate": "^6.2.0"
}
}
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -782,6 +782,11 @@
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.4.1.tgz#3382db2cd83ab565ed9626765e7da92944b45de8"
integrity sha512-o+pHCf/yMLSlV5MkDQEzEQL402i6SoRnktru+0rdSxVEFZcTzzGhZCAtZjUFyKGazMSv1TilzMg+RbED1N8XHQ==

"@rari-capital/solmate@^6.2.0":
version "6.2.0"
resolved "https://registry.yarnpkg.com/@rari-capital/solmate/-/solmate-6.2.0.tgz#4f70dc236606c27ec2cb1b4261dd830235d01fe4"
integrity sha512-g94F+Ra9ixyJyNgvnOIufNjUz488uEG0nxIEEtJ7+g+tA1XGUupRB2kB5b+VO7WYO26RNOVD2fW6xE4e14iWpg==

"@resolver-engine/core@^0.3.3":
version "0.3.3"
resolved "https://registry.yarnpkg.com/@resolver-engine/core/-/core-0.3.3.tgz#590f77d85d45bc7ecc4e06c654f41345db6ca967"
Expand Down

0 comments on commit 81d0225

Please sign in to comment.