wormhole/examples/EthSwapNGo/swapPool/contracts/simpleDex.sol

85 lines
3.7 KiB
Solidity
Raw Normal View History

pragma solidity ^0.6.7;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/math/SafeMath.sol";
interface TokenBridge {
function transferTokens(address token, uint256 amount, uint16 recipientChain, bytes32 recipient, uint256 arbiterFee, uint32 nonce) external payable returns (uint64);
}
//https://github.com/scaffold-eth/scaffold-eth/blob/mvp-dex/packages/hardhat/contracts/YourDEX.sol
contract SimpleDex {
using SafeMath for uint256;
string public purpose = "Swapping Rabbits";
IERC20 rabbits;
constructor(address tokenAddress) public {
rabbits = IERC20(tokenAddress);
}
uint256 public totalLiquidity;
mapping (address => uint256) public liquidity;
function init(uint256 tokens) public payable returns (uint256) {
require(totalLiquidity==0,"DEX:init - already has liquidity");
totalLiquidity = address(this).balance;
liquidity[msg.sender] = totalLiquidity;
require(rabbits.transferFrom(msg.sender, address(this), tokens));
return totalLiquidity;
}
function price(uint256 input_amount, uint256 input_reserve, uint256 output_reserve) public pure returns (uint256) {
uint256 input_amount_with_fee = input_amount.mul(997);
uint256 numerator = input_amount_with_fee.mul(output_reserve);
uint256 denominator = input_reserve.mul(1000).add(input_amount_with_fee);
return numerator / denominator;
}
function ethToToken() public payable returns (uint256) {
uint256 token_reserve = rabbits.balanceOf(address(this));
uint256 tokens_bought = price(msg.value, address(this).balance.sub(msg.value), token_reserve);
require(rabbits.transfer(msg.sender, tokens_bought));
return tokens_bought;
}
function tokenToEth(uint256 tokens) public returns (uint256) {
uint256 token_reserve = rabbits.balanceOf(address(this));
uint256 eth_bought = price(tokens, token_reserve, address(this).balance);
msg.sender.transfer(eth_bought);
require(rabbits.transferFrom(msg.sender, address(this), tokens));
return eth_bought;
}
function deposit() public payable returns (uint256) {
uint256 eth_reserve = address(this).balance.sub(msg.value);
uint256 token_reserve = rabbits.balanceOf(address(this));
uint256 token_amount = (msg.value.mul(token_reserve) / eth_reserve).add(1);
uint256 liquidity_minted = msg.value.mul(totalLiquidity) / eth_reserve;
liquidity[msg.sender] = liquidity[msg.sender].add(liquidity_minted);
totalLiquidity = totalLiquidity.add(liquidity_minted);
require(rabbits.transferFrom(msg.sender, address(this), token_amount));
return liquidity_minted;
}
function withdraw(uint256 amount) public returns (uint256, uint256) {
uint256 token_reserve = rabbits.balanceOf(address(this));
uint256 eth_amount = amount.mul(address(this).balance) / totalLiquidity;
uint256 token_amount = amount.mul(token_reserve) / totalLiquidity;
liquidity[msg.sender] = liquidity[msg.sender].sub(eth_amount);
totalLiquidity = totalLiquidity.sub(eth_amount);
msg.sender.transfer(eth_amount);
require(rabbits.transfer(msg.sender, token_amount));
return (eth_amount, token_amount);
}
function swapNGo(address _address, uint16 targetChain, bytes32 targetAddress, uint256 fee, uint32 nonce) public payable returns (uint64) {
uint256 token_reserve = rabbits.balanceOf(address(this));
uint256 tokens_bought = price(msg.value, address(this).balance.sub(msg.value), token_reserve);
rabbits.approve(_address, tokens_bought);
return TokenBridge(_address).transferTokens(address(rabbits), tokens_bought, targetChain, targetAddress, fee, nonce);
}
}