Posted By : Himanshu
In case you're inexperienced with Uniswap yet, it's a completely decentralized convention for computerized liquidity arrangement on Ethereum. A more clear depiction would be that it's a decentralized trade (DEX) depending on outside liquidity suppliers that can add tokens to shrewd agreement pools and clients can exchange those straightforwardly.
Since it's running on Ethereum, what we can exchange are Ethereum ERC-20 tokens. For every token, there is its own savvy agreement and liquidity pool. Uniswap - being completely decentralized - has no limitations to which tokens can be added. On the off chance that no agreements for a symbolic pair exist yet, anybody can make one utilizing their production line and anybody can give liquidity to a pool. A charge of 0.3% for each exchange is given to those liquidity suppliers as motivation.
The cost of a token is controlled by the liquidity in a pool. For instance, if a client is purchasing TOKEN1 with TOKEN2, the flexibility of TOKEN1 in the pool will diminish while the use of TOKEN2 will increase and the cost of TOKEN1 will also increase. Moreover, if a client is selling TOKEN1, the cost of TOKEN1 will diminish. Thusly the symbolic cost consistently mirrors the flexibility and request.
Also, obviously, a client doesn't need to be an individual, it tends to be a keen agreement. That permits us to add Uniswap to our own agreements for adding extra installment choices for clients of our agreements. Uniswap makes this cycle exceptionally helpful, see beneath for how to coordinate it.
One reason Uniswap is so well known might be the basic method of incorporating them into your own keen agreement. Suppose you have a framework where clients pay with DAI. With Uniswap in only a couple of lines of code, you could add the alternative for them to likewise pay in ETH. The ETH can be consequently changed over into DAI before the genuine rationale. It would look something like this
function pay(uint paymentAmountInDai) public payable {
if (msg.value > 0) {
convertEthToDai(paymentAmountInDai);
} else {
require(daiToken.transferFrom(msg.sender, address(this), paymentAmountInDai);
}
// do something with that DAI
...
}
A straightforward check toward the start of your capacity will be sufficient. Presently with respect to the convertEthToDai work, it will look like something this:
function convertEthToDai(uint daiAmount, uint deadline) public payable {
address[] memory path = new address[](2);
path[0] = uniswapRouter.WETH();
path[1] = daiToken;
uniswapRouter.swapETHForExactTokens.value(msg.value)(daiAmount, path, address(this), deadline);
// refund leftover ETH to user
msg.sender.call.value(address(this).balance)("");
}
There are several things to unpack here
The uniswapRouter will be a wrapper contract provided by Uniswap that has several safety mechanisms and convenience functions. Currently, it is recommended to use the Router02 contract. You can instantiate it using IUniswapV2Router02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D) for any main or testnet. The interface code can be found here.
Any swap needs to have a starting and end path. While in Uniswap v2 you can have a direct token to token pairs, it is not always guaranteed that such a pair actually exists. But you may still be able to trade them as long as you can find a path, e.g., Token1 → Token2 → WETH → Token3. In that case, you can still trade Token1 for Token3, it will only cost a little bit more than a direct swap.
You might notice that we are using WETH here. In Uniswap v2 there are no more direct ETH pairs, all ETH must be converted to WETH first. In our case, this is done by the router.
This function can be used to use ETH and receive an exact amount of tokens for it. Any leftover ETH will be refunded, so make sure you have a fallback function in your contract to receive ETH: receive() payable external {}. The deadline parameter will ensure that miners cannot withhold a swap and use it at a later, more profitable time. Make sure to pass this UNIX timestamp from your frontend, don't use it now inside the contract.
Once the trade is finished, we can return any leftover ETH to the user. This sends out all ETH from the contract, so if your contract might have an ETH balance for other reasons, make sure to change this.
One issue we have now is the point at which a client calls the compensation capacity and needs to pay in ETH, we don't have the foggiest idea of the amount ETH he needs. We can utilize the getAmountsIn capacity to figure precisely that.
function getEstimatedETHforDAI(uint daiAmount) public view returns (uint[] memory) {
address[] memory path = new address[](2);
path[0] = uniswapRouter.WETH();
path[1] = multiDaiKovan;
return uniswapRouter.getAmountsIn(daiAmount, path);
}
Presently we can call getEstimatedETHforDAI in our frontend. To guarantee we are sending enough ETH and that the exchange won't get returned, we can expand the assessed measure of ETH by a tad:
const requiredEth = (await myContract.getEstimatedETHforDAI(daiAmount))[0];
const sendEth = requiredEth * 1.1;
Here's a complete working model you can utilize straightforwardly on Remix. It permits you to exchange ETH for Multi-collateralized Kovan DAI:
pragma solidity 0.7.1;
import "https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/interfaces/IUniswapV2Router02.sol";
contract UniswapExample {
address internal constant UNISWAP_ROUTER_ADDRESS = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D ;
IUniswapV2Router02 public uniswapRouter;
address private multiDaiKovan = 0x4F96Fe3b7A6Cf9725f59d353F723c1bDb64CA6Aa;
constructor() {
uniswapRouter = IUniswapV2Router02(UNISWAP_ROUTER_ADDRESS);
}
function convertEthToDai(uint daiAmount) public payable {
uint deadline = block.timestamp + 15; // using 'now' for convenience, for mainnet pass deadline from frontend!
uniswapRouter.swapETHForExactTokens{ value: msg.value }(daiAmount, getPathForETHtoDAI(), address(this), deadline);
// refund leftover ETH to user
(bool success,) = msg.sender.call{ value: address(this).balance }("");
require(success, "refund failed");
}
function getEstimatedETHforDAI(uint daiAmount) public view returns (uint[] memory) {
return uniswapRouter.getAmountsIn(daiAmount, getPathForETHtoDAI());
}
function getPathForETHtoDAI() private view returns (address[] memory) {
address[] memory path = new address[](2);
path[0] = uniswapRouter.WETH();
path[1] = multiDaiKovan;
return path;
}
// important to receive ETH
receive() payable external {}
}
December 17, 2024 at 05:11 pm
Your comment is awaiting moderation.