├── contracts ├── interfaces │ ├── IUniswapFactory.sol │ └── IUniswapExchange.sol ├── uniswap │ ├── UniswapFactory.sol │ └── UniswapExchange.sol └── tokens │ └── ERC20.sol ├── abis ├── UniswapFactory.json └── UniswapExchange.json └── README.md /contracts/interfaces/IUniswapFactory.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.5.0; 2 | 3 | interface IUniswapFactory { 4 | event NewExchange(address indexed token, address indexed exchange); 5 | 6 | function initializeFactory(address template) external; 7 | function createExchange(address token) external returns (address payable); 8 | function getExchange(address token) external view returns (address payable); 9 | function getToken(address token) external view returns (address); 10 | function getTokenWihId(uint256 token_id) external view returns (address); 11 | function exchangeTemplate() external view returns (address); 12 | function tokenCount() external view returns (uint256); 13 | } -------------------------------------------------------------------------------- /contracts/uniswap/UniswapFactory.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.5.0; 2 | 3 | import "./UniswapExchange.sol"; 4 | import "../interfaces/IUniswapExchange.sol"; 5 | 6 | 7 | contract UniswapFactory { 8 | 9 | /***********************************| 10 | | Events And Variables | 11 | |__________________________________*/ 12 | 13 | event NewExchange(address indexed token, address indexed exchange); 14 | 15 | address public exchangeTemplate; 16 | uint256 public tokenCount; 17 | mapping (address => address) internal token_to_exchange; 18 | mapping (address => address) internal exchange_to_token; 19 | mapping (uint256 => address) internal id_to_token; 20 | 21 | /***********************************| 22 | | Factory Functions | 23 | |__________________________________*/ 24 | 25 | function initializeFactory(address template) public { 26 | require(exchangeTemplate == address(0)); 27 | require(template != address(0)); 28 | exchangeTemplate = template; 29 | } 30 | 31 | function createExchange(address token) public returns (address) { 32 | require(token != address(0)); 33 | require(exchangeTemplate != address(0)); 34 | require(token_to_exchange[token] == address(0)); 35 | address payable newEx = address(uint160(createClone(exchangeTemplate))); 36 | UniswapExchange exchange = UniswapExchange(newEx); 37 | exchange.setup(token); 38 | token_to_exchange[token] = address(exchange); 39 | exchange_to_token[address(exchange)] = token; 40 | uint256 token_id = tokenCount + 1; 41 | tokenCount = token_id; 42 | id_to_token[token_id] = token; 43 | emit NewExchange(token, address(exchange)); 44 | return address(exchange); 45 | } 46 | 47 | function createClone(address target) internal returns (address result) { 48 | bytes20 targetBytes = bytes20(target); 49 | assembly { 50 | let clone := mload(0x40) 51 | mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000) 52 | mstore(add(clone, 0x14), targetBytes) 53 | mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000) 54 | result := create(0, clone, 0x37) 55 | } 56 | } 57 | 58 | /***********************************| 59 | | Getter Functions | 60 | |__________________________________*/ 61 | 62 | function getExchange(address token) public view returns (address) { 63 | return token_to_exchange[token]; 64 | } 65 | 66 | function getToken(address exchange) public view returns (address) { 67 | return exchange_to_token[exchange]; 68 | } 69 | 70 | function getTokenWithId(uint256 token_id) public view returns (address) { 71 | return id_to_token[token_id]; 72 | } 73 | 74 | } 75 | 76 | -------------------------------------------------------------------------------- /abis/UniswapFactory.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": true, 7 | "internalType": "address", 8 | "name": "token", 9 | "type": "address" 10 | }, 11 | { 12 | "indexed": true, 13 | "internalType": "address", 14 | "name": "exchange", 15 | "type": "address" 16 | } 17 | ], 18 | "name": "NewExchange", 19 | "type": "event" 20 | }, 21 | { 22 | "constant": true, 23 | "inputs": [], 24 | "name": "exchangeTemplate", 25 | "outputs": [ 26 | { 27 | "internalType": "address", 28 | "name": "", 29 | "type": "address" 30 | } 31 | ], 32 | "payable": false, 33 | "stateMutability": "view", 34 | "type": "function" 35 | }, 36 | { 37 | "constant": true, 38 | "inputs": [], 39 | "name": "tokenCount", 40 | "outputs": [ 41 | { 42 | "internalType": "uint256", 43 | "name": "", 44 | "type": "uint256" 45 | } 46 | ], 47 | "payable": false, 48 | "stateMutability": "view", 49 | "type": "function" 50 | }, 51 | { 52 | "constant": false, 53 | "inputs": [ 54 | { 55 | "internalType": "address", 56 | "name": "template", 57 | "type": "address" 58 | } 59 | ], 60 | "name": "initializeFactory", 61 | "outputs": [], 62 | "payable": false, 63 | "stateMutability": "nonpayable", 64 | "type": "function" 65 | }, 66 | { 67 | "constant": false, 68 | "inputs": [ 69 | { 70 | "internalType": "address", 71 | "name": "token", 72 | "type": "address" 73 | } 74 | ], 75 | "name": "createExchange", 76 | "outputs": [ 77 | { 78 | "internalType": "address", 79 | "name": "", 80 | "type": "address" 81 | } 82 | ], 83 | "payable": false, 84 | "stateMutability": "nonpayable", 85 | "type": "function" 86 | }, 87 | { 88 | "constant": true, 89 | "inputs": [ 90 | { 91 | "internalType": "address", 92 | "name": "token", 93 | "type": "address" 94 | } 95 | ], 96 | "name": "getExchange", 97 | "outputs": [ 98 | { 99 | "internalType": "address", 100 | "name": "", 101 | "type": "address" 102 | } 103 | ], 104 | "payable": false, 105 | "stateMutability": "view", 106 | "type": "function" 107 | }, 108 | { 109 | "constant": true, 110 | "inputs": [ 111 | { 112 | "internalType": "address", 113 | "name": "exchange", 114 | "type": "address" 115 | } 116 | ], 117 | "name": "getToken", 118 | "outputs": [ 119 | { 120 | "internalType": "address", 121 | "name": "", 122 | "type": "address" 123 | } 124 | ], 125 | "payable": false, 126 | "stateMutability": "view", 127 | "type": "function" 128 | }, 129 | { 130 | "constant": true, 131 | "inputs": [ 132 | { 133 | "internalType": "uint256", 134 | "name": "token_id", 135 | "type": "uint256" 136 | } 137 | ], 138 | "name": "getTokenWithId", 139 | "outputs": [ 140 | { 141 | "internalType": "address", 142 | "name": "", 143 | "type": "address" 144 | } 145 | ], 146 | "payable": false, 147 | "stateMutability": "view", 148 | "type": "function" 149 | } 150 | ] 151 | -------------------------------------------------------------------------------- /contracts/tokens/ERC20.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.5.0; 2 | import "../utils/SafeMath.sol"; 3 | 4 | 5 | /** 6 | * @title Standard ERC20 token 7 | * 8 | * @dev Implementation of the basic standard token. 9 | * https://eips.ethereum.org/EIPS/eip-20 10 | * Originally based on code by FirstBlood: 11 | * https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol 12 | * 13 | * This implementation emits additional Approval events, allowing applications to reconstruct the allowance status for 14 | * all accounts just by listening to said events. Note that this isn't required by the specification, and other 15 | * compliant implementations may not do it. 16 | */ 17 | contract ERC20 { 18 | using SafeMath for uint256; 19 | 20 | mapping (address => uint256) internal _balances; 21 | mapping (address => mapping (address => uint256)) internal _allowed; 22 | 23 | event Transfer(address indexed from, address indexed to, uint256 value); 24 | event Approval(address indexed owner, address indexed spender, uint256 value); 25 | 26 | uint256 internal _totalSupply; 27 | 28 | /** 29 | * @dev Total number of tokens in existence 30 | */ 31 | function totalSupply() public view returns (uint256) { 32 | return _totalSupply; 33 | } 34 | 35 | /** 36 | * @dev Gets the balance of the specified address. 37 | * @param owner The address to query the balance of. 38 | * @return A uint256 representing the amount owned by the passed address. 39 | */ 40 | function balanceOf(address owner) public view returns (uint256) { 41 | return _balances[owner]; 42 | } 43 | 44 | /** 45 | * @dev Function to check the amount of tokens that an owner allowed to a spender. 46 | * @param owner address The address which owns the funds. 47 | * @param spender address The address which will spend the funds. 48 | * @return A uint256 specifying the amount of tokens still available for the spender. 49 | */ 50 | function allowance(address owner, address spender) public view returns (uint256) { 51 | return _allowed[owner][spender]; 52 | } 53 | 54 | /** 55 | * @dev Transfer token to a specified address 56 | * @param to The address to transfer to. 57 | * @param value The amount to be transferred. 58 | */ 59 | function transfer(address to, uint256 value) public returns (bool) { 60 | _transfer(msg.sender, to, value); 61 | return true; 62 | } 63 | 64 | /** 65 | * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender. 66 | * Beware that changing an allowance with this method brings the risk that someone may use both the old 67 | * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this 68 | * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: 69 | * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 70 | * @param spender The address which will spend the funds. 71 | * @param value The amount of tokens to be spent. 72 | */ 73 | function approve(address spender, uint256 value) public returns (bool) { 74 | _approve(msg.sender, spender, value); 75 | return true; 76 | } 77 | 78 | /** 79 | * @dev Transfer tokens from one address to another. 80 | * Note that while this function emits an Approval event, this is not required as per the specification, 81 | * and other compliant implementations may not emit the event. 82 | * @param from address The address which you want to send tokens from 83 | * @param to address The address which you want to transfer to 84 | * @param value uint256 the amount of tokens to be transferred 85 | */ 86 | function transferFrom(address from, address to, uint256 value) public returns (bool) { 87 | _transfer(from, to, value); 88 | _approve(from, msg.sender, _allowed[from][msg.sender].sub(value)); 89 | return true; 90 | } 91 | 92 | /** 93 | * @dev Increase the amount of tokens that an owner allowed to a spender. 94 | * approve should be called when _allowed[msg.sender][spender] == 0. To increment 95 | * allowed value is better to use this function to avoid 2 calls (and wait until 96 | * the first transaction is mined) 97 | * From MonolithDAO Token.sol 98 | * Emits an Approval event. 99 | * @param spender The address which will spend the funds. 100 | * @param addedValue The amount of tokens to increase the allowance by. 101 | */ 102 | function increaseAllowance(address spender, uint256 addedValue) public returns (bool) { 103 | _approve(msg.sender, spender, _allowed[msg.sender][spender].add(addedValue)); 104 | return true; 105 | } 106 | 107 | /** 108 | * @dev Decrease the amount of tokens that an owner allowed to a spender. 109 | * approve should be called when _allowed[msg.sender][spender] == 0. To decrement 110 | * allowed value is better to use this function to avoid 2 calls (and wait until 111 | * the first transaction is mined) 112 | * From MonolithDAO Token.sol 113 | * Emits an Approval event. 114 | * @param spender The address which will spend the funds. 115 | * @param subtractedValue The amount of tokens to decrease the allowance by. 116 | */ 117 | function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) { 118 | _approve(msg.sender, spender, _allowed[msg.sender][spender].sub(subtractedValue)); 119 | return true; 120 | } 121 | 122 | /** 123 | * @dev Transfer token for a specified addresses 124 | * @param from The address to transfer from. 125 | * @param to The address to transfer to. 126 | * @param value The amount to be transferred. 127 | */ 128 | function _transfer(address from, address to, uint256 value) internal { 129 | require(to != address(0)); 130 | 131 | _balances[from] = _balances[from].sub(value); 132 | _balances[to] = _balances[to].add(value); 133 | emit Transfer(from, to, value); 134 | } 135 | 136 | /** 137 | * @dev Internal function that mints an amount of the token and assigns it to 138 | * an account. This encapsulates the modification of balances such that the 139 | * proper events are emitted. 140 | * @param account The account that will receive the created tokens. 141 | * @param value The amount that will be created. 142 | */ 143 | function _mint(address account, uint256 value) internal { 144 | require(account != address(0)); 145 | 146 | _totalSupply = _totalSupply.add(value); 147 | _balances[account] = _balances[account].add(value); 148 | emit Transfer(address(0), account, value); 149 | } 150 | 151 | /** 152 | * @dev Internal function that burns an amount of the token of a given 153 | * account. 154 | * @param account The account whose tokens will be burnt. 155 | * @param value The amount that will be burnt. 156 | */ 157 | function _burn(address account, uint256 value) internal { 158 | require(account != address(0)); 159 | 160 | _totalSupply = _totalSupply.sub(value); 161 | _balances[account] = _balances[account].sub(value); 162 | emit Transfer(account, address(0), value); 163 | } 164 | 165 | /** 166 | * @dev Approve an address to spend another addresses' tokens. 167 | * @param owner The address that owns the tokens. 168 | * @param spender The address that will spend the tokens. 169 | * @param value The number of tokens that can be spent. 170 | */ 171 | function _approve(address owner, address spender, uint256 value) internal { 172 | require(spender != address(0)); 173 | require(owner != address(0)); 174 | 175 | _allowed[owner][spender] = value; 176 | emit Approval(owner, spender, value); 177 | } 178 | 179 | /** 180 | * @dev Internal function that burns an amount of the token of a given 181 | * account, deducting from the sender's allowance for said account. Uses the 182 | * internal burn function. 183 | * Emits an Approval event (reflecting the reduced allowance). 184 | * @param account The account whose tokens will be burnt. 185 | * @param value The amount that will be burnt. 186 | */ 187 | function _burnFrom(address account, uint256 value) internal { 188 | _burn(account, value); 189 | _approve(account, msg.sender, _allowed[account][msg.sender].sub(value)); 190 | } 191 | } 192 | -------------------------------------------------------------------------------- /contracts/interfaces/IUniswapExchange.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.5.0; 2 | 3 | interface IUniswapExchange { 4 | event TokenPurchase(address indexed buyer, uint256 indexed eth_sold, uint256 indexed tokens_bought); 5 | event EthPurchase(address indexed buyer, uint256 indexed tokens_sold, uint256 indexed eth_bought); 6 | event AddLiquidity(address indexed provider, uint256 indexed eth_amount, uint256 indexed token_amount); 7 | event RemoveLiquidity(address indexed provider, uint256 indexed eth_amount, uint256 indexed token_amount); 8 | 9 | /** 10 | * @notice Convert ETH to Tokens. 11 | * @dev User specifies exact input (msg.value). 12 | * @dev User cannot specify minimum output or deadline. 13 | */ 14 | function () external payable; 15 | 16 | /** 17 | * @dev Pricing function for converting between ETH && Tokens. 18 | * @param input_amount Amount of ETH or Tokens being sold. 19 | * @param input_reserve Amount of ETH or Tokens (input type) in exchange reserves. 20 | * @param output_reserve Amount of ETH or Tokens (output type) in exchange reserves. 21 | * @return Amount of ETH or Tokens bought. 22 | */ 23 | function getInputPrice(uint256 input_amount, uint256 input_reserve, uint256 output_reserve) external view returns (uint256); 24 | 25 | /** 26 | * @dev Pricing function for converting between ETH && Tokens. 27 | * @param output_amount Amount of ETH or Tokens being bought. 28 | * @param input_reserve Amount of ETH or Tokens (input type) in exchange reserves. 29 | * @param output_reserve Amount of ETH or Tokens (output type) in exchange reserves. 30 | * @return Amount of ETH or Tokens sold. 31 | */ 32 | function getOutputPrice(uint256 output_amount, uint256 input_reserve, uint256 output_reserve) external view returns (uint256); 33 | 34 | 35 | /** 36 | * @notice Convert ETH to Tokens. 37 | * @dev User specifies exact input (msg.value) && minimum output. 38 | * @param min_tokens Minimum Tokens bought. 39 | * @param deadline Time after which this transaction can no longer be executed. 40 | * @return Amount of Tokens bought. 41 | */ 42 | function ethToTokenSwapInput(uint256 min_tokens, uint256 deadline) external payable returns (uint256); 43 | 44 | /** 45 | * @notice Convert ETH to Tokens && transfers Tokens to recipient. 46 | * @dev User specifies exact input (msg.value) && minimum output 47 | * @param min_tokens Minimum Tokens bought. 48 | * @param deadline Time after which this transaction can no longer be executed. 49 | * @param recipient The address that receives output Tokens. 50 | * @return Amount of Tokens bought. 51 | */ 52 | function ethToTokenTransferInput(uint256 min_tokens, uint256 deadline, address recipient) external payable returns(uint256); 53 | 54 | 55 | /** 56 | * @notice Convert ETH to Tokens. 57 | * @dev User specifies maximum input (msg.value) && exact output. 58 | * @param tokens_bought Amount of tokens bought. 59 | * @param deadline Time after which this transaction can no longer be executed. 60 | * @return Amount of ETH sold. 61 | */ 62 | function ethToTokenSwapOutput(uint256 tokens_bought, uint256 deadline) external payable returns(uint256); 63 | /** 64 | * @notice Convert ETH to Tokens && transfers Tokens to recipient. 65 | * @dev User specifies maximum input (msg.value) && exact output. 66 | * @param tokens_bought Amount of tokens bought. 67 | * @param deadline Time after which this transaction can no longer be executed. 68 | * @param recipient The address that receives output Tokens. 69 | * @return Amount of ETH sold. 70 | */ 71 | function ethToTokenTransferOutput(uint256 tokens_bought, uint256 deadline, address recipient) external payable returns (uint256); 72 | 73 | /** 74 | * @notice Convert Tokens to ETH. 75 | * @dev User specifies exact input && minimum output. 76 | * @param tokens_sold Amount of Tokens sold. 77 | * @param min_eth Minimum ETH purchased. 78 | * @param deadline Time after which this transaction can no longer be executed. 79 | * @return Amount of ETH bought. 80 | */ 81 | function tokenToEthSwapInput(uint256 tokens_sold, uint256 min_eth, uint256 deadline) external returns (uint256); 82 | 83 | /** 84 | * @notice Convert Tokens to ETH && transfers ETH to recipient. 85 | * @dev User specifies exact input && minimum output. 86 | * @param tokens_sold Amount of Tokens sold. 87 | * @param min_eth Minimum ETH purchased. 88 | * @param deadline Time after which this transaction can no longer be executed. 89 | * @param recipient The address that receives output ETH. 90 | * @return Amount of ETH bought. 91 | */ 92 | function tokenToEthTransferInput(uint256 tokens_sold, uint256 min_eth, uint256 deadline, address recipient) external returns (uint256); 93 | 94 | /** 95 | * @notice Convert Tokens to ETH. 96 | * @dev User specifies maximum input && exact output. 97 | * @param eth_bought Amount of ETH purchased. 98 | * @param max_tokens Maximum Tokens sold. 99 | * @param deadline Time after which this transaction can no longer be executed. 100 | * @return Amount of Tokens sold. 101 | */ 102 | function tokenToEthSwapOutput(uint256 eth_bought, uint256 max_tokens, uint256 deadline) external returns (uint256); 103 | 104 | /** 105 | * @notice Convert Tokens to ETH && transfers ETH to recipient. 106 | * @dev User specifies maximum input && exact output. 107 | * @param eth_bought Amount of ETH purchased. 108 | * @param max_tokens Maximum Tokens sold. 109 | * @param deadline Time after which this transaction can no longer be executed. 110 | * @param recipient The address that receives output ETH. 111 | * @return Amount of Tokens sold. 112 | */ 113 | function tokenToEthTransferOutput(uint256 eth_bought, uint256 max_tokens, uint256 deadline, address recipient) external returns (uint256); 114 | 115 | /** 116 | * @notice Convert Tokens (token) to Tokens (token_addr). 117 | * @dev User specifies exact input && minimum output. 118 | * @param tokens_sold Amount of Tokens sold. 119 | * @param min_tokens_bought Minimum Tokens (token_addr) purchased. 120 | * @param min_eth_bought Minimum ETH purchased as intermediary. 121 | * @param deadline Time after which this transaction can no longer be executed. 122 | * @param token_addr The address of the token being purchased. 123 | * @return Amount of Tokens (token_addr) bought. 124 | */ 125 | function tokenToTokenSwapInput( 126 | uint256 tokens_sold, 127 | uint256 min_tokens_bought, 128 | uint256 min_eth_bought, 129 | uint256 deadline, 130 | address token_addr) 131 | external returns (uint256); 132 | 133 | /** 134 | * @notice Convert Tokens (token) to Tokens (token_addr) && transfers 135 | * Tokens (token_addr) to recipient. 136 | * @dev User specifies exact input && minimum output. 137 | * @param tokens_sold Amount of Tokens sold. 138 | * @param min_tokens_bought Minimum Tokens (token_addr) purchased. 139 | * @param min_eth_bought Minimum ETH purchased as intermediary. 140 | * @param deadline Time after which this transaction can no longer be executed. 141 | * @param recipient The address that receives output ETH. 142 | * @param token_addr The address of the token being purchased. 143 | * @return Amount of Tokens (token_addr) bought. 144 | */ 145 | function tokenToTokenTransferInput( 146 | uint256 tokens_sold, 147 | uint256 min_tokens_bought, 148 | uint256 min_eth_bought, 149 | uint256 deadline, 150 | address recipient, 151 | address token_addr) 152 | external returns (uint256); 153 | 154 | 155 | /** 156 | * @notice Convert Tokens (token) to Tokens (token_addr). 157 | * @dev User specifies maximum input && exact output. 158 | * @param tokens_bought Amount of Tokens (token_addr) bought. 159 | * @param max_tokens_sold Maximum Tokens (token) sold. 160 | * @param max_eth_sold Maximum ETH purchased as intermediary. 161 | * @param deadline Time after which this transaction can no longer be executed. 162 | * @param token_addr The address of the token being purchased. 163 | * @return Amount of Tokens (token) sold. 164 | */ 165 | function tokenToTokenSwapOutput( 166 | uint256 tokens_bought, 167 | uint256 max_tokens_sold, 168 | uint256 max_eth_sold, 169 | uint256 deadline, 170 | address token_addr) 171 | external returns (uint256); 172 | 173 | /** 174 | * @notice Convert Tokens (token) to Tokens (token_addr) && transfers 175 | * Tokens (token_addr) to recipient. 176 | * @dev User specifies maximum input && exact output. 177 | * @param tokens_bought Amount of Tokens (token_addr) bought. 178 | * @param max_tokens_sold Maximum Tokens (token) sold. 179 | * @param max_eth_sold Maximum ETH purchased as intermediary. 180 | * @param deadline Time after which this transaction can no longer be executed. 181 | * @param recipient The address that receives output ETH. 182 | * @param token_addr The address of the token being purchased. 183 | * @return Amount of Tokens (token) sold. 184 | */ 185 | function tokenToTokenTransferOutput( 186 | uint256 tokens_bought, 187 | uint256 max_tokens_sold, 188 | uint256 max_eth_sold, 189 | uint256 deadline, 190 | address recipient, 191 | address token_addr) 192 | external returns (uint256); 193 | 194 | /** 195 | * @notice Convert Tokens (token) to Tokens (exchange_addr.token). 196 | * @dev Allows trades through contracts that were not deployed from the same factory. 197 | * @dev User specifies exact input && minimum output. 198 | * @param tokens_sold Amount of Tokens sold. 199 | * @param min_tokens_bought Minimum Tokens (token_addr) purchased. 200 | * @param min_eth_bought Minimum ETH purchased as intermediary. 201 | * @param deadline Time after which this transaction can no longer be executed. 202 | * @param exchange_addr The address of the exchange for the token being purchased. 203 | * @return Amount of Tokens (exchange_addr.token) bought. 204 | */ 205 | function tokenToExchangeSwapInput( 206 | uint256 tokens_sold, 207 | uint256 min_tokens_bought, 208 | uint256 min_eth_bought, 209 | uint256 deadline, 210 | address exchange_addr) 211 | external returns (uint256); 212 | 213 | /** 214 | * @notice Convert Tokens (token) to Tokens (exchange_addr.token) && transfers 215 | * Tokens (exchange_addr.token) to recipient. 216 | * @dev Allows trades through contracts that were not deployed from the same factory. 217 | * @dev User specifies exact input && minimum output. 218 | * @param tokens_sold Amount of Tokens sold. 219 | * @param min_tokens_bought Minimum Tokens (token_addr) purchased. 220 | * @param min_eth_bought Minimum ETH purchased as intermediary. 221 | * @param deadline Time after which this transaction can no longer be executed. 222 | * @param recipient The address that receives output ETH. 223 | * @param exchange_addr The address of the exchange for the token being purchased. 224 | * @return Amount of Tokens (exchange_addr.token) bought. 225 | */ 226 | function tokenToExchangeTransferInput( 227 | uint256 tokens_sold, 228 | uint256 min_tokens_bought, 229 | uint256 min_eth_bought, 230 | uint256 deadline, 231 | address recipient, 232 | address exchange_addr) 233 | external returns (uint256); 234 | 235 | /** 236 | * @notice Convert Tokens (token) to Tokens (exchange_addr.token). 237 | * @dev Allows trades through contracts that were not deployed from the same factory. 238 | * @dev User specifies maximum input && exact output. 239 | * @param tokens_bought Amount of Tokens (token_addr) bought. 240 | * @param max_tokens_sold Maximum Tokens (token) sold. 241 | * @param max_eth_sold Maximum ETH purchased as intermediary. 242 | * @param deadline Time after which this transaction can no longer be executed. 243 | * @param exchange_addr The address of the exchange for the token being purchased. 244 | * @return Amount of Tokens (token) sold. 245 | */ 246 | function tokenToExchangeSwapOutput( 247 | uint256 tokens_bought, 248 | uint256 max_tokens_sold, 249 | uint256 max_eth_sold, 250 | uint256 deadline, 251 | address exchange_addr) 252 | external returns (uint256); 253 | 254 | /** 255 | * @notice Convert Tokens (token) to Tokens (exchange_addr.token) && transfers 256 | * Tokens (exchange_addr.token) to recipient. 257 | * @dev Allows trades through contracts that were not deployed from the same factory. 258 | * @dev User specifies maximum input && exact output. 259 | * @param tokens_bought Amount of Tokens (token_addr) bought. 260 | * @param max_tokens_sold Maximum Tokens (token) sold. 261 | * @param max_eth_sold Maximum ETH purchased as intermediary. 262 | * @param deadline Time after which this transaction can no longer be executed. 263 | * @param recipient The address that receives output ETH. 264 | * @param exchange_addr The address of the exchange for the token being purchased. 265 | * @return Amount of Tokens (token) sold. 266 | */ 267 | function tokenToExchangeTransferOutput( 268 | uint256 tokens_bought, 269 | uint256 max_tokens_sold, 270 | uint256 max_eth_sold, 271 | uint256 deadline, 272 | address recipient, 273 | address exchange_addr) 274 | external returns (uint256); 275 | 276 | 277 | /***********************************| 278 | | Getter Functions | 279 | |__________________________________*/ 280 | 281 | /** 282 | * @notice external price function for ETH to Token trades with an exact input. 283 | * @param eth_sold Amount of ETH sold. 284 | * @return Amount of Tokens that can be bought with input ETH. 285 | */ 286 | function getEthToTokenInputPrice(uint256 eth_sold) external view returns (uint256); 287 | 288 | /** 289 | * @notice external price function for ETH to Token trades with an exact output. 290 | * @param tokens_bought Amount of Tokens bought. 291 | * @return Amount of ETH needed to buy output Tokens. 292 | */ 293 | function getEthToTokenOutputPrice(uint256 tokens_bought) external view returns (uint256); 294 | 295 | /** 296 | * @notice external price function for Token to ETH trades with an exact input. 297 | * @param tokens_sold Amount of Tokens sold. 298 | * @return Amount of ETH that can be bought with input Tokens. 299 | */ 300 | function getTokenToEthInputPrice(uint256 tokens_sold) external view returns (uint256); 301 | 302 | /** 303 | * @notice external price function for Token to ETH trades with an exact output. 304 | * @param eth_bought Amount of output ETH. 305 | * @return Amount of Tokens needed to buy output ETH. 306 | */ 307 | function getTokenToEthOutputPrice(uint256 eth_bought) external view returns (uint256); 308 | 309 | /** 310 | * @return Address of Token that is sold on this exchange. 311 | */ 312 | function tokenAddress() external view returns (address); 313 | 314 | /** 315 | * @return Address of factory that created this exchange. 316 | */ 317 | function factoryAddress() external view returns (address); 318 | 319 | 320 | /***********************************| 321 | | Liquidity Functions | 322 | |__________________________________*/ 323 | 324 | /** 325 | * @notice Deposit ETH && Tokens (token) at current ratio to mint UNI tokens. 326 | * @dev min_liquidity does nothing when total UNI supply is 0. 327 | * @param min_liquidity Minimum number of UNI sender will mint if total UNI supply is greater than 0. 328 | * @param max_tokens Maximum number of tokens deposited. Deposits max amount if total UNI supply is 0. 329 | * @param deadline Time after which this transaction can no longer be executed. 330 | * @return The amount of UNI minted. 331 | */ 332 | function addLiquidity(uint256 min_liquidity, uint256 max_tokens, uint256 deadline) external payable returns (uint256); 333 | 334 | /** 335 | * @dev Burn UNI tokens to withdraw ETH && Tokens at current ratio. 336 | * @param amount Amount of UNI burned. 337 | * @param min_eth Minimum ETH withdrawn. 338 | * @param min_tokens Minimum Tokens withdrawn. 339 | * @param deadline Time after which this transaction can no longer be executed. 340 | * @return The amount of ETH && Tokens withdrawn. 341 | */ 342 | function removeLiquidity(uint256 amount, uint256 min_eth, uint256 min_tokens, uint256 deadline) external returns (uint256, uint256); 343 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TTSwap 2 | TTSwap is a DEX (decentralized exchange) on the ThunderCore blockchain based on the model: Automated Market-Making (AMM) inspired by [Uniswap](https://uniswap.org/docs/v1). 3 | ## Information 4 | 5 | - Website [TTSwap](https://ttswap.space) 6 | - [Address of Factory](https://viewblock.io/thundercore/address/0xce393b11872ee5020828e443f6ec9de58cd8b6c5?tab=code) 7 | - [Implementation of Exchange](https://viewblock.io/thundercore/address/0x7c1e1a39703ab5c21b5537d4093ccd1117ded405?tab=code) 8 | 9 | ## Documents 10 | * [IUniswapExchange](#iuniswapexchange) 11 | * [AddLiquidity](#event-addliquidity) 12 | * [EthPurchase](#event-ethpurchase) 13 | * [RemoveLiquidity](#event-removeliquidity) 14 | * [TokenPurchase](#event-tokenpurchase) 15 | * [addLiquidity](#function-addliquidity) 16 | * [ethToTokenSwapInput](#function-ethtotokenswapinput) 17 | * [ethToTokenSwapOutput](#function-ethtotokenswapoutput) 18 | * [ethToTokenTransferInput](#function-ethtotokentransferinput) 19 | * [ethToTokenTransferOutput](#function-ethtotokentransferoutput) 20 | * [factoryAddress](#function-factoryaddress) 21 | * [getEthToTokenInputPrice](#function-getethtotokeninputprice) 22 | * [getEthToTokenOutputPrice](#function-getethtotokenoutputprice) 23 | * [getInputPrice](#function-getinputprice) 24 | * [getOutputPrice](#function-getoutputprice) 25 | * [getTokenToEthInputPrice](#function-gettokentoethinputprice) 26 | * [getTokenToEthOutputPrice](#function-gettokentoethoutputprice) 27 | * [removeLiquidity](#function-removeliquidity) 28 | * [tokenAddress](#function-tokenaddress) 29 | * [tokenToEthSwapInput](#function-tokentoethswapinput) 30 | * [tokenToEthSwapOutput](#function-tokentoethswapoutput) 31 | * [tokenToEthTransferInput](#function-tokentoethtransferinput) 32 | * [tokenToEthTransferOutput](#function-tokentoethtransferoutput) 33 | * [tokenToExchangeSwapInput](#function-tokentoexchangeswapinput) 34 | * [tokenToExchangeSwapOutput](#function-tokentoexchangeswapoutput) 35 | * [tokenToExchangeTransferInput](#function-tokentoexchangetransferinput) 36 | * [tokenToExchangeTransferOutput](#function-tokentoexchangetransferoutput) 37 | * [tokenToTokenSwapInput](#function-tokentotokenswapinput) 38 | * [tokenToTokenSwapOutput](#function-tokentotokenswapoutput) 39 | * [tokenToTokenTransferInput](#function-tokentotokentransferinput) 40 | * [tokenToTokenTransferOutput](#function-tokentotokentransferoutput) 41 | 42 | ## IUniswapExchange 43 | 44 | ### *event* AddLiquidity 45 | 46 | IUniswapExchange.AddLiquidity(provider, eth_amount, token_amount) `06239653` 47 | 48 | Arguments 49 | 50 | | **type** | **name** | **description** | 51 | |-|-|-| 52 | | *address* | provider | indexed | 53 | | *uint256* | eth_amount | indexed | 54 | | *uint256* | token_amount | indexed | 55 | 56 | ### *event* EthPurchase 57 | 58 | IUniswapExchange.EthPurchase(buyer, tokens_sold, eth_bought) `7f4091b4` 59 | 60 | Arguments 61 | 62 | | **type** | **name** | **description** | 63 | |-|-|-| 64 | | *address* | buyer | indexed | 65 | | *uint256* | tokens_sold | indexed | 66 | | *uint256* | eth_bought | indexed | 67 | 68 | ### *event* RemoveLiquidity 69 | 70 | IUniswapExchange.RemoveLiquidity(provider, eth_amount, token_amount) `0fbf06c0` 71 | 72 | Arguments 73 | 74 | | **type** | **name** | **description** | 75 | |-|-|-| 76 | | *address* | provider | indexed | 77 | | *uint256* | eth_amount | indexed | 78 | | *uint256* | token_amount | indexed | 79 | 80 | ### *event* TokenPurchase 81 | 82 | IUniswapExchange.TokenPurchase(buyer, eth_sold, tokens_bought) `cd60aa75` 83 | 84 | Arguments 85 | 86 | | **type** | **name** | **description** | 87 | |-|-|-| 88 | | *address* | buyer | indexed | 89 | | *uint256* | eth_sold | indexed | 90 | | *uint256* | tokens_bought | indexed | 91 | 92 | 93 | 94 | ### *function* addLiquidity 95 | 96 | IUniswapExchange.addLiquidity(min_liquidity, max_tokens, deadline) `payable` `422f1043` 97 | 98 | **Deposit ETH && Tokens (token) at current ratio to mint UNI tokens.** 99 | 100 | > min_liquidity does nothing when total UNI supply is 0. 101 | 102 | Inputs 103 | 104 | | **type** | **name** | **description** | 105 | |-|-|-| 106 | | *uint256* | min_liquidity | Minimum number of UNI sender will mint if total UNI supply is greater than 0. | 107 | | *uint256* | max_tokens | Maximum number of tokens deposited. Deposits max amount if total UNI supply is 0. | 108 | | *uint256* | deadline | Time after which this transaction can no longer be executed. | 109 | 110 | Outputs 111 | 112 | | **type** | **name** | **description** | 113 | |-|-|-| 114 | | *uint256* | | uint256 The amount of UNI minted. | 115 | 116 | ### *function* ethToTokenSwapInput 117 | 118 | IUniswapExchange.ethToTokenSwapInput(min_tokens, deadline) `payable` `f39b5b9b` 119 | 120 | **Convert ETH to Tokens.** 121 | 122 | > User specifies exact input (msg.value) && minimum output. 123 | 124 | Inputs 125 | 126 | | **type** | **name** | **description** | 127 | |-|-|-| 128 | | *uint256* | min_tokens | Minimum Tokens bought. | 129 | | *uint256* | deadline | Time after which this transaction can no longer be executed. | 130 | 131 | Outputs 132 | 133 | | **type** | **name** | **description** | 134 | |-|-|-| 135 | | *uint256* | | Amount of Tokens bought. | 136 | 137 | ### *function* ethToTokenSwapOutput 138 | 139 | IUniswapExchange.ethToTokenSwapOutput(tokens_bought, deadline) `payable` `6b1d4db7` 140 | 141 | **Convert ETH to Tokens.** 142 | 143 | > User specifies maximum input (msg.value) && exact output. 144 | 145 | Inputs 146 | 147 | | **type** | **name** | **description** | 148 | |-|-|-| 149 | | *uint256* | tokens_bought | Amount of tokens bought. | 150 | | *uint256* | deadline | Time after which this transaction can no longer be executed. | 151 | 152 | Outputs 153 | 154 | | **type** | **name** | **description** | 155 | |-|-|-| 156 | | *uint256* | | Amount of ETH sold. | 157 | 158 | ### *function* ethToTokenTransferInput 159 | 160 | IUniswapExchange.ethToTokenTransferInput(min_tokens, deadline, recipient) `payable` `ad65d76d` 161 | 162 | **Convert ETH to Tokens && transfers Tokens to recipient.** 163 | 164 | > User specifies exact input (msg.value) && minimum output 165 | 166 | Inputs 167 | 168 | | **type** | **name** | **description** | 169 | |-|-|-| 170 | | *uint256* | min_tokens | Minimum Tokens bought. | 171 | | *uint256* | deadline | Time after which this transaction can no longer be executed. | 172 | | *address* | recipient | The address that receives output Tokens. | 173 | 174 | Outputs 175 | 176 | | **type** | **name** | **description** | 177 | |-|-|-| 178 | | *uint256* | | Amount of Tokens bought. | 179 | 180 | ### *function* ethToTokenTransferOutput 181 | 182 | IUniswapExchange.ethToTokenTransferOutput(tokens_bought, deadline, recipient) `payable` `0b573638` 183 | 184 | **Convert ETH to Tokens && transfers Tokens to recipient.** 185 | 186 | > User specifies maximum input (msg.value) && exact output. 187 | 188 | Inputs 189 | 190 | | **type** | **name** | **description** | 191 | |-|-|-| 192 | | *uint256* | tokens_bought | Amount of tokens bought. | 193 | | *uint256* | deadline | Time after which this transaction can no longer be executed. | 194 | | *address* | recipient | The address that receives output Tokens. | 195 | 196 | Outputs 197 | 198 | | **type** | **name** | **description** | 199 | |-|-|-| 200 | | *uint256* | | Amount of ETH sold. | 201 | 202 | ### *function* factoryAddress 203 | 204 | IUniswapExchange.factoryAddress() `view` `966dae0e` 205 | 206 | 207 | 208 | 209 | Outputs 210 | 211 | | **type** | **name** | **description** | 212 | |-|-|-| 213 | | *address* | | Address of factory that created this exchange. | 214 | 215 | ### *function* getEthToTokenInputPrice 216 | 217 | IUniswapExchange.getEthToTokenInputPrice(eth_sold) `view` `cd7724c3` 218 | 219 | **external price function for ETH to Token trades with an exact input.** 220 | 221 | 222 | Inputs 223 | 224 | | **type** | **name** | **description** | 225 | |-|-|-| 226 | | *uint256* | eth_sold | Amount of ETH sold. | 227 | 228 | Outputs 229 | 230 | | **type** | **name** | **description** | 231 | |-|-|-| 232 | | *uint256* | | Amount of Tokens that can be bought with input ETH. | 233 | 234 | ### *function* getEthToTokenOutputPrice 235 | 236 | IUniswapExchange.getEthToTokenOutputPrice(tokens_bought) `view` `59e94862` 237 | 238 | **external price function for ETH to Token trades with an exact output.** 239 | 240 | 241 | Inputs 242 | 243 | | **type** | **name** | **description** | 244 | |-|-|-| 245 | | *uint256* | tokens_bought | Amount of Tokens bought. | 246 | 247 | Outputs 248 | 249 | | **type** | **name** | **description** | 250 | |-|-|-| 251 | | *uint256* | | Amount of ETH needed to buy output Tokens. | 252 | 253 | ### *function* getInputPrice 254 | 255 | IUniswapExchange.getInputPrice(input_amount, input_reserve, output_reserve) `view` `89f2a871` 256 | 257 | > Pricing function for converting between ETH && Tokens. 258 | 259 | Inputs 260 | 261 | | **type** | **name** | **description** | 262 | |-|-|-| 263 | | *uint256* | input_amount | Amount of ETH or Tokens being sold. | 264 | | *uint256* | input_reserve | Amount of ETH or Tokens (input type) in exchange reserves. | 265 | | *uint256* | output_reserve | Amount of ETH or Tokens (output type) in exchange reserves. | 266 | 267 | Outputs 268 | 269 | | **type** | **name** | **description** | 270 | |-|-|-| 271 | | *uint256* | | Amount of ETH or Tokens bought. | 272 | 273 | ### *function* getOutputPrice 274 | 275 | IUniswapExchange.getOutputPrice(output_amount, input_reserve, output_reserve) `view` `fd11c223` 276 | 277 | > Pricing function for converting between ETH && Tokens. 278 | 279 | Inputs 280 | 281 | | **type** | **name** | **description** | 282 | |-|-|-| 283 | | *uint256* | output_amount | Amount of ETH or Tokens being bought. | 284 | | *uint256* | input_reserve | Amount of ETH or Tokens (input type) in exchange reserves. | 285 | | *uint256* | output_reserve | Amount of ETH or Tokens (output type) in exchange reserves. | 286 | 287 | Outputs 288 | 289 | | **type** | **name** | **description** | 290 | |-|-|-| 291 | | *uint256* | | Amount of ETH or Tokens sold. | 292 | 293 | ### *function* getTokenToEthInputPrice 294 | 295 | IUniswapExchange.getTokenToEthInputPrice(tokens_sold) `view` `95b68fe7` 296 | 297 | **external price function for Token to ETH trades with an exact input.** 298 | 299 | 300 | Inputs 301 | 302 | | **type** | **name** | **description** | 303 | |-|-|-| 304 | | *uint256* | tokens_sold | Amount of Tokens sold. | 305 | 306 | Outputs 307 | 308 | | **type** | **name** | **description** | 309 | |-|-|-| 310 | | *uint256* | | Amount of ETH that can be bought with input Tokens. | 311 | 312 | ### *function* getTokenToEthOutputPrice 313 | 314 | IUniswapExchange.getTokenToEthOutputPrice(eth_bought) `view` `2640f62c` 315 | 316 | **external price function for Token to ETH trades with an exact output.** 317 | 318 | 319 | Inputs 320 | 321 | | **type** | **name** | **description** | 322 | |-|-|-| 323 | | *uint256* | eth_bought | Amount of output ETH. | 324 | 325 | Outputs 326 | 327 | | **type** | **name** | **description** | 328 | |-|-|-| 329 | | *uint256* | | Amount of Tokens needed to buy output ETH. | 330 | 331 | ### *function* removeLiquidity 332 | 333 | IUniswapExchange.removeLiquidity(amount, min_eth, min_tokens, deadline) `nonpayable` `f88bf15a` 334 | 335 | > Burn UNI tokens to withdraw ETH && Tokens at current ratio. 336 | 337 | Inputs 338 | 339 | | **type** | **name** | **description** | 340 | |-|-|-| 341 | | *uint256* | amount | Amount of UNI burned. | 342 | | *uint256* | min_eth | Minimum ETH withdrawn. | 343 | | *uint256* | min_tokens | Minimum Tokens withdrawn. | 344 | | *uint256* | deadline | Time after which this transaction can no longer be executed. | 345 | 346 | Outputs 347 | 348 | | **type** | **name** | **description** | 349 | |-|-|-| 350 | | *uint256* | | The amount of ETH && Tokens withdrawn. | 351 | | *uint256* | | The amount of ETH && Tokens withdrawn. | 352 | 353 | ### *function* tokenAddress 354 | 355 | IUniswapExchange.tokenAddress() `view` `9d76ea58` 356 | 357 | 358 | 359 | 360 | Outputs 361 | 362 | | **type** | **name** | **description** | 363 | |-|-|-| 364 | | *address* | | Address of Token that is sold on this exchange. | 365 | 366 | ### *function* tokenToEthSwapInput 367 | 368 | IUniswapExchange.tokenToEthSwapInput(tokens_sold, min_eth, deadline) `nonpayable` `95e3c50b` 369 | 370 | **Convert Tokens to ETH.** 371 | 372 | > User specifies exact input && minimum output. 373 | 374 | Inputs 375 | 376 | | **type** | **name** | **description** | 377 | |-|-|-| 378 | | *uint256* | tokens_sold | Amount of Tokens sold. | 379 | | *uint256* | min_eth | Minimum ETH purchased. | 380 | | *uint256* | deadline | Time after which this transaction can no longer be executed. | 381 | 382 | Outputs 383 | 384 | | **type** | **name** | **description** | 385 | |-|-|-| 386 | | *uint256* | | Amount of ETH bought. | 387 | 388 | ### *function* tokenToEthSwapOutput 389 | 390 | IUniswapExchange.tokenToEthSwapOutput(eth_bought, max_tokens, deadline) `nonpayable` `013efd8b` 391 | 392 | **Convert Tokens to ETH.** 393 | 394 | > User specifies maximum input && exact output. 395 | 396 | Inputs 397 | 398 | | **type** | **name** | **description** | 399 | |-|-|-| 400 | | *uint256* | eth_bought | Amount of ETH purchased. | 401 | | *uint256* | max_tokens | Maximum Tokens sold. | 402 | | *uint256* | deadline | Time after which this transaction can no longer be executed. | 403 | 404 | Outputs 405 | 406 | | **type** | **name** | **description** | 407 | |-|-|-| 408 | | *uint256* | | Amount of Tokens sold. | 409 | 410 | ### *function* tokenToEthTransferInput 411 | 412 | IUniswapExchange.tokenToEthTransferInput(tokens_sold, min_eth, deadline, recipient) `nonpayable` `7237e031` 413 | 414 | **Convert Tokens to ETH && transfers ETH to recipient.** 415 | 416 | > User specifies exact input && minimum output. 417 | 418 | Inputs 419 | 420 | | **type** | **name** | **description** | 421 | |-|-|-| 422 | | *uint256* | tokens_sold | Amount of Tokens sold. | 423 | | *uint256* | min_eth | Minimum ETH purchased. | 424 | | *uint256* | deadline | Time after which this transaction can no longer be executed. | 425 | | *address* | recipient | The address that receives output ETH. | 426 | 427 | Outputs 428 | 429 | | **type** | **name** | **description** | 430 | |-|-|-| 431 | | *uint256* | | Amount of ETH bought. | 432 | 433 | ### *function* tokenToEthTransferOutput 434 | 435 | IUniswapExchange.tokenToEthTransferOutput(eth_bought, max_tokens, deadline, recipient) `nonpayable` `d4e4841d` 436 | 437 | **Convert Tokens to ETH && transfers ETH to recipient.** 438 | 439 | > User specifies maximum input && exact output. 440 | 441 | Inputs 442 | 443 | | **type** | **name** | **description** | 444 | |-|-|-| 445 | | *uint256* | eth_bought | Amount of ETH purchased. | 446 | | *uint256* | max_tokens | Maximum Tokens sold. | 447 | | *uint256* | deadline | Time after which this transaction can no longer be executed. | 448 | | *address* | recipient | The address that receives output ETH. | 449 | 450 | Outputs 451 | 452 | | **type** | **name** | **description** | 453 | |-|-|-| 454 | | *uint256* | | Amount of Tokens sold. | 455 | 456 | ### *function* tokenToExchangeSwapInput 457 | 458 | IUniswapExchange.tokenToExchangeSwapInput(tokens_sold, min_tokens_bought, min_eth_bought, deadline, exchange_addr) `nonpayable` `b1cb43bf` 459 | 460 | **Convert Tokens (token) to Tokens (exchange_addr.token).** 461 | 462 | > Allows trades through contracts that were not deployed from the same factory.User specifies exact input && minimum output. 463 | 464 | Inputs 465 | 466 | | **type** | **name** | **description** | 467 | |-|-|-| 468 | | *uint256* | tokens_sold | Amount of Tokens sold. | 469 | | *uint256* | min_tokens_bought | Minimum Tokens (token_addr) purchased. | 470 | | *uint256* | min_eth_bought | Minimum ETH purchased as intermediary. | 471 | | *uint256* | deadline | Time after which this transaction can no longer be executed. | 472 | | *address* | exchange_addr | The address of the exchange for the token being purchased. | 473 | 474 | Outputs 475 | 476 | | **type** | **name** | **description** | 477 | |-|-|-| 478 | | *uint256* | | Amount of Tokens (exchange_addr.token) bought. | 479 | 480 | ### *function* tokenToExchangeSwapOutput 481 | 482 | IUniswapExchange.tokenToExchangeSwapOutput(tokens_bought, max_tokens_sold, max_eth_sold, deadline, exchange_addr) `nonpayable` `ea650c7d` 483 | 484 | **Convert Tokens (token) to Tokens (exchange_addr.token).** 485 | 486 | > Allows trades through contracts that were not deployed from the same factory.User specifies maximum input && exact output. 487 | 488 | Inputs 489 | 490 | | **type** | **name** | **description** | 491 | |-|-|-| 492 | | *uint256* | tokens_bought | Amount of Tokens (token_addr) bought. | 493 | | *uint256* | max_tokens_sold | Maximum Tokens (token) sold. | 494 | | *uint256* | max_eth_sold | Maximum ETH purchased as intermediary. | 495 | | *uint256* | deadline | Time after which this transaction can no longer be executed. | 496 | | *address* | exchange_addr | The address of the exchange for the token being purchased. | 497 | 498 | Outputs 499 | 500 | | **type** | **name** | **description** | 501 | |-|-|-| 502 | | *uint256* | | Amount of Tokens (token) sold. | 503 | 504 | ### *function* tokenToExchangeTransferInput 505 | 506 | IUniswapExchange.tokenToExchangeTransferInput(tokens_sold, min_tokens_bought, min_eth_bought, deadline, recipient, exchange_addr) `nonpayable` `ec384a3e` 507 | 508 | **Convert Tokens (token) to Tokens (exchange_addr.token) && transfers Tokens (exchange_addr.token) to recipient.** 509 | 510 | > Allows trades through contracts that were not deployed from the same factory.User specifies exact input && minimum output. 511 | 512 | Inputs 513 | 514 | | **type** | **name** | **description** | 515 | |-|-|-| 516 | | *uint256* | tokens_sold | Amount of Tokens sold. | 517 | | *uint256* | min_tokens_bought | Minimum Tokens (token_addr) purchased. | 518 | | *uint256* | min_eth_bought | Minimum ETH purchased as intermediary. | 519 | | *uint256* | deadline | Time after which this transaction can no longer be executed. | 520 | | *address* | recipient | The address that receives output ETH. | 521 | | *address* | exchange_addr | The address of the exchange for the token being purchased. | 522 | 523 | Outputs 524 | 525 | | **type** | **name** | **description** | 526 | |-|-|-| 527 | | *uint256* | | Amount of Tokens (exchange_addr.token) bought. | 528 | 529 | ### *function* tokenToExchangeTransferOutput 530 | 531 | IUniswapExchange.tokenToExchangeTransferOutput(tokens_bought, max_tokens_sold, max_eth_sold, deadline, recipient, exchange_addr) `nonpayable` `981a1327` 532 | 533 | **Convert Tokens (token) to Tokens (exchange_addr.token) && transfers Tokens (exchange_addr.token) to recipient.** 534 | 535 | > Allows trades through contracts that were not deployed from the same factory.User specifies maximum input && exact output. 536 | 537 | Inputs 538 | 539 | | **type** | **name** | **description** | 540 | |-|-|-| 541 | | *uint256* | tokens_bought | Amount of Tokens (token_addr) bought. | 542 | | *uint256* | max_tokens_sold | Maximum Tokens (token) sold. | 543 | | *uint256* | max_eth_sold | Maximum ETH purchased as intermediary. | 544 | | *uint256* | deadline | Time after which this transaction can no longer be executed. | 545 | | *address* | recipient | The address that receives output ETH. | 546 | | *address* | exchange_addr | The address of the exchange for the token being purchased. | 547 | 548 | Outputs 549 | 550 | | **type** | **name** | **description** | 551 | |-|-|-| 552 | | *uint256* | | Amount of Tokens (token) sold. | 553 | 554 | ### *function* tokenToTokenSwapInput 555 | 556 | IUniswapExchange.tokenToTokenSwapInput(tokens_sold, min_tokens_bought, min_eth_bought, deadline, token_addr) `nonpayable` `ddf7e1a7` 557 | 558 | **Convert Tokens (token) to Tokens (token_addr).** 559 | 560 | > User specifies exact input && minimum output. 561 | 562 | Inputs 563 | 564 | | **type** | **name** | **description** | 565 | |-|-|-| 566 | | *uint256* | tokens_sold | Amount of Tokens sold. | 567 | | *uint256* | min_tokens_bought | Minimum Tokens (token_addr) purchased. | 568 | | *uint256* | min_eth_bought | Minimum ETH purchased as intermediary. | 569 | | *uint256* | deadline | Time after which this transaction can no longer be executed. | 570 | | *address* | token_addr | The address of the token being purchased. | 571 | 572 | Outputs 573 | 574 | | **type** | **name** | **description** | 575 | |-|-|-| 576 | | *uint256* | | Amount of Tokens (token_addr) bought. | 577 | 578 | ### *function* tokenToTokenSwapOutput 579 | 580 | IUniswapExchange.tokenToTokenSwapOutput(tokens_bought, max_tokens_sold, max_eth_sold, deadline, token_addr) `nonpayable` `b040d545` 581 | 582 | **Convert Tokens (token) to Tokens (token_addr).** 583 | 584 | > User specifies maximum input && exact output. 585 | 586 | Inputs 587 | 588 | | **type** | **name** | **description** | 589 | |-|-|-| 590 | | *uint256* | tokens_bought | Amount of Tokens (token_addr) bought. | 591 | | *uint256* | max_tokens_sold | Maximum Tokens (token) sold. | 592 | | *uint256* | max_eth_sold | Maximum ETH purchased as intermediary. | 593 | | *uint256* | deadline | Time after which this transaction can no longer be executed. | 594 | | *address* | token_addr | The address of the token being purchased. | 595 | 596 | Outputs 597 | 598 | | **type** | **name** | **description** | 599 | |-|-|-| 600 | | *uint256* | | Amount of Tokens (token) sold. | 601 | 602 | ### *function* tokenToTokenTransferInput 603 | 604 | IUniswapExchange.tokenToTokenTransferInput(tokens_sold, min_tokens_bought, min_eth_bought, deadline, recipient, token_addr) `nonpayable` `f552d91b` 605 | 606 | **Convert Tokens (token) to Tokens (token_addr) && transfers Tokens (token_addr) to recipient.** 607 | 608 | > User specifies exact input && minimum output. 609 | 610 | Inputs 611 | 612 | | **type** | **name** | **description** | 613 | |-|-|-| 614 | | *uint256* | tokens_sold | Amount of Tokens sold. | 615 | | *uint256* | min_tokens_bought | Minimum Tokens (token_addr) purchased. | 616 | | *uint256* | min_eth_bought | Minimum ETH purchased as intermediary. | 617 | | *uint256* | deadline | Time after which this transaction can no longer be executed. | 618 | | *address* | recipient | The address that receives output ETH. | 619 | | *address* | token_addr | The address of the token being purchased. | 620 | 621 | Outputs 622 | 623 | | **type** | **name** | **description** | 624 | |-|-|-| 625 | | *uint256* | | Amount of Tokens (token_addr) bought. | 626 | 627 | ### *function* tokenToTokenTransferOutput 628 | 629 | IUniswapExchange.tokenToTokenTransferOutput(tokens_bought, max_tokens_sold, max_eth_sold, deadline, recipient, token_addr) `nonpayable` `f3c0efe9` 630 | 631 | **Convert Tokens (token) to Tokens (token_addr) && transfers Tokens (token_addr) to recipient.** 632 | 633 | > User specifies maximum input && exact output. 634 | 635 | Inputs 636 | 637 | | **type** | **name** | **description** | 638 | |-|-|-| 639 | | *uint256* | tokens_bought | Amount of Tokens (token_addr) bought. | 640 | | *uint256* | max_tokens_sold | Maximum Tokens (token) sold. | 641 | | *uint256* | max_eth_sold | Maximum ETH purchased as intermediary. | 642 | | *uint256* | deadline | Time after which this transaction can no longer be executed. | 643 | | *address* | recipient | The address that receives output ETH. | 644 | | *address* | token_addr | The address of the token being purchased. | 645 | 646 | Outputs 647 | 648 | | **type** | **name** | **description** | 649 | |-|-|-| 650 | | *uint256* | | Amount of Tokens (token) sold. | 651 | 652 | --- -------------------------------------------------------------------------------- /contracts/uniswap/UniswapExchange.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.5.0; 2 | import "../tokens/ERC20.sol"; 3 | import "../interfaces/IERC20.sol"; 4 | import "../interfaces/IUniswapFactory.sol"; 5 | import "../interfaces/IUniswapExchange.sol"; 6 | 7 | 8 | contract UniswapExchange is ERC20 { 9 | 10 | /***********************************| 11 | | Variables && Events | 12 | |__________________________________*/ 13 | 14 | // Variables 15 | bytes32 public name; // Uniswap V1 16 | bytes32 public symbol; // UNI-V1 17 | uint256 public decimals; // 18 18 | IERC20 token; // address of the ERC20 token traded on this contract 19 | IUniswapFactory factory; // interface for the factory that created this contract 20 | 21 | // Events 22 | event TokenPurchase(address indexed buyer, uint256 indexed eth_sold, uint256 indexed tokens_bought); 23 | event EthPurchase(address indexed buyer, uint256 indexed tokens_sold, uint256 indexed eth_bought); 24 | event AddLiquidity(address indexed provider, uint256 indexed eth_amount, uint256 indexed token_amount); 25 | event RemoveLiquidity(address indexed provider, uint256 indexed eth_amount, uint256 indexed token_amount); 26 | 27 | 28 | /***********************************| 29 | | Constsructor | 30 | |__________________________________*/ 31 | 32 | /** 33 | * @dev This function acts as a contract constructor which is not currently supported in contracts deployed 34 | * using create_with_code_of(). It is called once by the factory during contract creation. 35 | */ 36 | function setup(address token_addr) public { 37 | require( 38 | address(factory) == address(0) && address(token) == address(0) && token_addr != address(0), 39 | "INVALID_ADDRESS" 40 | ); 41 | factory = IUniswapFactory(msg.sender); 42 | token = IERC20(token_addr); 43 | name = 0x556e697377617020563100000000000000000000000000000000000000000000; 44 | symbol = 0x554e492d56310000000000000000000000000000000000000000000000000000; 45 | decimals = 18; 46 | } 47 | 48 | 49 | /***********************************| 50 | | Exchange Functions | 51 | |__________________________________*/ 52 | 53 | 54 | /** 55 | * @notice Convert ETH to Tokens. 56 | * @dev User specifies exact input (msg.value). 57 | * @dev User cannot specify minimum output or deadline. 58 | */ 59 | function () external payable { 60 | ethToTokenInput(msg.value, 1, block.timestamp, msg.sender, msg.sender); 61 | } 62 | 63 | /** 64 | * @dev Pricing function for converting between ETH && Tokens. 65 | * @param input_amount Amount of ETH or Tokens being sold. 66 | * @param input_reserve Amount of ETH or Tokens (input type) in exchange reserves. 67 | * @param output_reserve Amount of ETH or Tokens (output type) in exchange reserves. 68 | * @return Amount of ETH or Tokens bought. 69 | */ 70 | function getInputPrice(uint256 input_amount, uint256 input_reserve, uint256 output_reserve) public view returns (uint256) { 71 | require(input_reserve > 0 && output_reserve > 0, "INVALID_VALUE"); 72 | uint256 input_amount_with_fee = input_amount.mul(997); 73 | uint256 numerator = input_amount_with_fee.mul(output_reserve); 74 | uint256 denominator = input_reserve.mul(1000).add(input_amount_with_fee); 75 | return numerator / denominator; 76 | } 77 | 78 | /** 79 | * @dev Pricing function for converting between ETH && Tokens. 80 | * @param output_amount Amount of ETH or Tokens being bought. 81 | * @param input_reserve Amount of ETH or Tokens (input type) in exchange reserves. 82 | * @param output_reserve Amount of ETH or Tokens (output type) in exchange reserves. 83 | * @return Amount of ETH or Tokens sold. 84 | */ 85 | function getOutputPrice(uint256 output_amount, uint256 input_reserve, uint256 output_reserve) public view returns (uint256) { 86 | require(input_reserve > 0 && output_reserve > 0); 87 | uint256 numerator = input_reserve.mul(output_amount).mul(1000); 88 | uint256 denominator = (output_reserve.sub(output_amount)).mul(997); 89 | return (numerator / denominator).add(1); 90 | } 91 | 92 | function ethToTokenInput(uint256 eth_sold, uint256 min_tokens, uint256 deadline, address buyer, address recipient) private returns (uint256) { 93 | require(deadline >= block.timestamp && eth_sold > 0 && min_tokens > 0); 94 | uint256 token_reserve = token.balanceOf(address(this)); 95 | uint256 tokens_bought = getInputPrice(eth_sold, address(this).balance.sub(eth_sold), token_reserve); 96 | require(tokens_bought >= min_tokens); 97 | require(token.transfer(recipient, tokens_bought)); 98 | emit TokenPurchase(buyer, eth_sold, tokens_bought); 99 | return tokens_bought; 100 | } 101 | 102 | /** 103 | * @notice Convert ETH to Tokens. 104 | * @dev User specifies exact input (msg.value) && minimum output. 105 | * @param min_tokens Minimum Tokens bought. 106 | * @param deadline Time after which this transaction can no longer be executed. 107 | * @return Amount of Tokens bought. 108 | */ 109 | function ethToTokenSwapInput(uint256 min_tokens, uint256 deadline) public payable returns (uint256) { 110 | return ethToTokenInput(msg.value, min_tokens, deadline, msg.sender, msg.sender); 111 | } 112 | 113 | /** 114 | * @notice Convert ETH to Tokens && transfers Tokens to recipient. 115 | * @dev User specifies exact input (msg.value) && minimum output 116 | * @param min_tokens Minimum Tokens bought. 117 | * @param deadline Time after which this transaction can no longer be executed. 118 | * @param recipient The address that receives output Tokens. 119 | * @return Amount of Tokens bought. 120 | */ 121 | function ethToTokenTransferInput(uint256 min_tokens, uint256 deadline, address recipient) public payable returns(uint256) { 122 | require(recipient != address(this) && recipient != address(0)); 123 | return ethToTokenInput(msg.value, min_tokens, deadline, msg.sender, recipient); 124 | } 125 | 126 | function ethToTokenOutput(uint256 tokens_bought, uint256 max_eth, uint256 deadline, address payable buyer, address recipient) private returns (uint256) { 127 | require(deadline >= block.timestamp && tokens_bought > 0 && max_eth > 0); 128 | uint256 token_reserve = token.balanceOf(address(this)); 129 | uint256 eth_sold = getOutputPrice(tokens_bought, address(this).balance.sub(max_eth), token_reserve); 130 | // Throws if eth_sold > max_eth 131 | uint256 eth_refund = max_eth.sub(eth_sold); 132 | if (eth_refund > 0) { 133 | buyer.transfer(eth_refund); 134 | } 135 | require(token.transfer(recipient, tokens_bought)); 136 | emit TokenPurchase(buyer, eth_sold, tokens_bought); 137 | return eth_sold; 138 | } 139 | 140 | /** 141 | * @notice Convert ETH to Tokens. 142 | * @dev User specifies maximum input (msg.value) && exact output. 143 | * @param tokens_bought Amount of tokens bought. 144 | * @param deadline Time after which this transaction can no longer be executed. 145 | * @return Amount of ETH sold. 146 | */ 147 | function ethToTokenSwapOutput(uint256 tokens_bought, uint256 deadline) public payable returns(uint256) { 148 | return ethToTokenOutput(tokens_bought, msg.value, deadline, msg.sender, msg.sender); 149 | } 150 | 151 | /** 152 | * @notice Convert ETH to Tokens && transfers Tokens to recipient. 153 | * @dev User specifies maximum input (msg.value) && exact output. 154 | * @param tokens_bought Amount of tokens bought. 155 | * @param deadline Time after which this transaction can no longer be executed. 156 | * @param recipient The address that receives output Tokens. 157 | * @return Amount of ETH sold. 158 | */ 159 | function ethToTokenTransferOutput(uint256 tokens_bought, uint256 deadline, address recipient) public payable returns (uint256) { 160 | require(recipient != address(this) && recipient != address(0)); 161 | return ethToTokenOutput(tokens_bought, msg.value, deadline, msg.sender, recipient); 162 | } 163 | 164 | function tokenToEthInput(uint256 tokens_sold, uint256 min_eth, uint256 deadline, address buyer, address payable recipient) private returns (uint256) { 165 | require(deadline >= block.timestamp && tokens_sold > 0 && min_eth > 0); 166 | uint256 token_reserve = token.balanceOf(address(this)); 167 | uint256 eth_bought = getInputPrice(tokens_sold, token_reserve, address(this).balance); 168 | uint256 wei_bought = eth_bought; 169 | require(wei_bought >= min_eth); 170 | recipient.transfer(wei_bought); 171 | require(token.transferFrom(buyer, address(this), tokens_sold)); 172 | emit EthPurchase(buyer, tokens_sold, wei_bought); 173 | return wei_bought; 174 | } 175 | 176 | /** 177 | * @notice Convert Tokens to ETH. 178 | * @dev User specifies exact input && minimum output. 179 | * @param tokens_sold Amount of Tokens sold. 180 | * @param min_eth Minimum ETH purchased. 181 | * @param deadline Time after which this transaction can no longer be executed. 182 | * @return Amount of ETH bought. 183 | */ 184 | function tokenToEthSwapInput(uint256 tokens_sold, uint256 min_eth, uint256 deadline) public returns (uint256) { 185 | return tokenToEthInput(tokens_sold, min_eth, deadline, msg.sender, msg.sender); 186 | } 187 | 188 | /** 189 | * @notice Convert Tokens to ETH && transfers ETH to recipient. 190 | * @dev User specifies exact input && minimum output. 191 | * @param tokens_sold Amount of Tokens sold. 192 | * @param min_eth Minimum ETH purchased. 193 | * @param deadline Time after which this transaction can no longer be executed. 194 | * @param recipient The address that receives output ETH. 195 | * @return Amount of ETH bought. 196 | */ 197 | function tokenToEthTransferInput(uint256 tokens_sold, uint256 min_eth, uint256 deadline, address payable recipient) public returns (uint256) { 198 | require(recipient != address(this) && recipient != address(0)); 199 | return tokenToEthInput(tokens_sold, min_eth, deadline, msg.sender, recipient); 200 | } 201 | 202 | 203 | function tokenToEthOutput(uint256 eth_bought, uint256 max_tokens, uint256 deadline, address buyer, address payable recipient) private returns (uint256) { 204 | require(deadline >= block.timestamp && eth_bought > 0); 205 | uint256 token_reserve = token.balanceOf(address(this)); 206 | uint256 tokens_sold = getOutputPrice(eth_bought, token_reserve, address(this).balance); 207 | // tokens sold is always > 0 208 | require(max_tokens >= tokens_sold); 209 | recipient.transfer(eth_bought); 210 | require(token.transferFrom(buyer, address(this), tokens_sold)); 211 | emit EthPurchase(buyer, tokens_sold, eth_bought); 212 | return tokens_sold; 213 | } 214 | 215 | /** 216 | * @notice Convert Tokens to ETH. 217 | * @dev User specifies maximum input && exact output. 218 | * @param eth_bought Amount of ETH purchased. 219 | * @param max_tokens Maximum Tokens sold. 220 | * @param deadline Time after which this transaction can no longer be executed. 221 | * @return Amount of Tokens sold. 222 | */ 223 | function tokenToEthSwapOutput(uint256 eth_bought, uint256 max_tokens, uint256 deadline) public returns (uint256) { 224 | return tokenToEthOutput(eth_bought, max_tokens, deadline, msg.sender, msg.sender); 225 | } 226 | 227 | /** 228 | * @notice Convert Tokens to ETH && transfers ETH to recipient. 229 | * @dev User specifies maximum input && exact output. 230 | * @param eth_bought Amount of ETH purchased. 231 | * @param max_tokens Maximum Tokens sold. 232 | * @param deadline Time after which this transaction can no longer be executed. 233 | * @param recipient The address that receives output ETH. 234 | * @return Amount of Tokens sold. 235 | */ 236 | function tokenToEthTransferOutput(uint256 eth_bought, uint256 max_tokens, uint256 deadline, address payable recipient) public returns (uint256) { 237 | require(recipient != address(this) && recipient != address(0)); 238 | return tokenToEthOutput(eth_bought, max_tokens, deadline, msg.sender, recipient); 239 | } 240 | 241 | function tokenToTokenInput( 242 | uint256 tokens_sold, 243 | uint256 min_tokens_bought, 244 | uint256 min_eth_bought, 245 | uint256 deadline, 246 | address buyer, 247 | address recipient, 248 | address payable exchange_addr) 249 | private returns (uint256) 250 | { 251 | require(deadline >= block.timestamp && tokens_sold > 0 && min_tokens_bought > 0 && min_eth_bought > 0); 252 | require(exchange_addr != address(this) && exchange_addr != address(0)); 253 | uint256 token_reserve = token.balanceOf(address(this)); 254 | uint256 eth_bought = getInputPrice(tokens_sold, token_reserve, address(this).balance); 255 | uint256 wei_bought = eth_bought; 256 | require(wei_bought >= min_eth_bought); 257 | require(token.transferFrom(buyer, address(this), tokens_sold)); 258 | uint256 tokens_bought = IUniswapExchange(exchange_addr).ethToTokenTransferInput.value(wei_bought)(min_tokens_bought, deadline, recipient); 259 | emit EthPurchase(buyer, tokens_sold, wei_bought); 260 | return tokens_bought; 261 | } 262 | 263 | /** 264 | * @notice Convert Tokens (token) to Tokens (token_addr). 265 | * @dev User specifies exact input && minimum output. 266 | * @param tokens_sold Amount of Tokens sold. 267 | * @param min_tokens_bought Minimum Tokens (token_addr) purchased. 268 | * @param min_eth_bought Minimum ETH purchased as intermediary. 269 | * @param deadline Time after which this transaction can no longer be executed. 270 | * @param token_addr The address of the token being purchased. 271 | * @return Amount of Tokens (token_addr) bought. 272 | */ 273 | function tokenToTokenSwapInput( 274 | uint256 tokens_sold, 275 | uint256 min_tokens_bought, 276 | uint256 min_eth_bought, 277 | uint256 deadline, 278 | address token_addr) 279 | public returns (uint256) 280 | { 281 | address payable exchange_addr = factory.getExchange(token_addr); 282 | return tokenToTokenInput(tokens_sold, min_tokens_bought, min_eth_bought, deadline, msg.sender, msg.sender, exchange_addr); 283 | } 284 | 285 | /** 286 | * @notice Convert Tokens (token) to Tokens (token_addr) && transfers 287 | * Tokens (token_addr) to recipient. 288 | * @dev User specifies exact input && minimum output. 289 | * @param tokens_sold Amount of Tokens sold. 290 | * @param min_tokens_bought Minimum Tokens (token_addr) purchased. 291 | * @param min_eth_bought Minimum ETH purchased as intermediary. 292 | * @param deadline Time after which this transaction can no longer be executed. 293 | * @param recipient The address that receives output ETH. 294 | * @param token_addr The address of the token being purchased. 295 | * @return Amount of Tokens (token_addr) bought. 296 | */ 297 | function tokenToTokenTransferInput( 298 | uint256 tokens_sold, 299 | uint256 min_tokens_bought, 300 | uint256 min_eth_bought, 301 | uint256 deadline, 302 | address recipient, 303 | address token_addr) 304 | public returns (uint256) 305 | { 306 | address payable exchange_addr = factory.getExchange(token_addr); 307 | return tokenToTokenInput(tokens_sold, min_tokens_bought, min_eth_bought, deadline, msg.sender, recipient, exchange_addr); 308 | } 309 | 310 | function tokenToTokenOutput( 311 | uint256 tokens_bought, 312 | uint256 max_tokens_sold, 313 | uint256 max_eth_sold, 314 | uint256 deadline, 315 | address buyer, 316 | address recipient, 317 | address payable exchange_addr) 318 | private returns (uint256) 319 | { 320 | require(deadline >= block.timestamp && (tokens_bought > 0 && max_eth_sold > 0)); 321 | require(exchange_addr != address(this) && exchange_addr != address(0)); 322 | uint256 eth_bought = IUniswapExchange(exchange_addr).getEthToTokenOutputPrice(tokens_bought); 323 | uint256 token_reserve = token.balanceOf(address(this)); 324 | uint256 tokens_sold = getOutputPrice(eth_bought, token_reserve, address(this).balance); 325 | // tokens sold is always > 0 326 | require(max_tokens_sold >= tokens_sold && max_eth_sold >= eth_bought); 327 | require(token.transferFrom(buyer, address(this), tokens_sold)); 328 | uint256 eth_sold = IUniswapExchange(exchange_addr).ethToTokenTransferOutput.value(eth_bought)(tokens_bought, deadline, recipient); 329 | emit EthPurchase(buyer, tokens_sold, eth_bought); 330 | return tokens_sold; 331 | } 332 | 333 | /** 334 | * @notice Convert Tokens (token) to Tokens (token_addr). 335 | * @dev User specifies maximum input && exact output. 336 | * @param tokens_bought Amount of Tokens (token_addr) bought. 337 | * @param max_tokens_sold Maximum Tokens (token) sold. 338 | * @param max_eth_sold Maximum ETH purchased as intermediary. 339 | * @param deadline Time after which this transaction can no longer be executed. 340 | * @param token_addr The address of the token being purchased. 341 | * @return Amount of Tokens (token) sold. 342 | */ 343 | function tokenToTokenSwapOutput( 344 | uint256 tokens_bought, 345 | uint256 max_tokens_sold, 346 | uint256 max_eth_sold, 347 | uint256 deadline, 348 | address token_addr) 349 | public returns (uint256) 350 | { 351 | address payable exchange_addr = factory.getExchange(token_addr); 352 | return tokenToTokenOutput(tokens_bought, max_tokens_sold, max_eth_sold, deadline, msg.sender, msg.sender, exchange_addr); 353 | } 354 | 355 | /** 356 | * @notice Convert Tokens (token) to Tokens (token_addr) && transfers 357 | * Tokens (token_addr) to recipient. 358 | * @dev User specifies maximum input && exact output. 359 | * @param tokens_bought Amount of Tokens (token_addr) bought. 360 | * @param max_tokens_sold Maximum Tokens (token) sold. 361 | * @param max_eth_sold Maximum ETH purchased as intermediary. 362 | * @param deadline Time after which this transaction can no longer be executed. 363 | * @param recipient The address that receives output ETH. 364 | * @param token_addr The address of the token being purchased. 365 | * @return Amount of Tokens (token) sold. 366 | */ 367 | function tokenToTokenTransferOutput( 368 | uint256 tokens_bought, 369 | uint256 max_tokens_sold, 370 | uint256 max_eth_sold, 371 | uint256 deadline, 372 | address recipient, 373 | address token_addr) 374 | public returns (uint256) 375 | { 376 | address payable exchange_addr = factory.getExchange(token_addr); 377 | return tokenToTokenOutput(tokens_bought, max_tokens_sold, max_eth_sold, deadline, msg.sender, recipient, exchange_addr); 378 | } 379 | 380 | /** 381 | * @notice Convert Tokens (token) to Tokens (exchange_addr.token). 382 | * @dev Allows trades through contracts that were not deployed from the same factory. 383 | * @dev User specifies exact input && minimum output. 384 | * @param tokens_sold Amount of Tokens sold. 385 | * @param min_tokens_bought Minimum Tokens (token_addr) purchased. 386 | * @param min_eth_bought Minimum ETH purchased as intermediary. 387 | * @param deadline Time after which this transaction can no longer be executed. 388 | * @param exchange_addr The address of the exchange for the token being purchased. 389 | * @return Amount of Tokens (exchange_addr.token) bought. 390 | */ 391 | function tokenToExchangeSwapInput( 392 | uint256 tokens_sold, 393 | uint256 min_tokens_bought, 394 | uint256 min_eth_bought, 395 | uint256 deadline, 396 | address payable exchange_addr) 397 | public returns (uint256) 398 | { 399 | return tokenToTokenInput(tokens_sold, min_tokens_bought, min_eth_bought, deadline, msg.sender, msg.sender, exchange_addr); 400 | } 401 | 402 | /** 403 | * @notice Convert Tokens (token) to Tokens (exchange_addr.token) && transfers 404 | * Tokens (exchange_addr.token) to recipient. 405 | * @dev Allows trades through contracts that were not deployed from the same factory. 406 | * @dev User specifies exact input && minimum output. 407 | * @param tokens_sold Amount of Tokens sold. 408 | * @param min_tokens_bought Minimum Tokens (token_addr) purchased. 409 | * @param min_eth_bought Minimum ETH purchased as intermediary. 410 | * @param deadline Time after which this transaction can no longer be executed. 411 | * @param recipient The address that receives output ETH. 412 | * @param exchange_addr The address of the exchange for the token being purchased. 413 | * @return Amount of Tokens (exchange_addr.token) bought. 414 | */ 415 | function tokenToExchangeTransferInput( 416 | uint256 tokens_sold, 417 | uint256 min_tokens_bought, 418 | uint256 min_eth_bought, 419 | uint256 deadline, 420 | address recipient, 421 | address payable exchange_addr) 422 | public returns (uint256) 423 | { 424 | require(recipient != address(this)); 425 | return tokenToTokenInput(tokens_sold, min_tokens_bought, min_eth_bought, deadline, msg.sender, recipient, exchange_addr); 426 | } 427 | 428 | /** 429 | * @notice Convert Tokens (token) to Tokens (exchange_addr.token). 430 | * @dev Allows trades through contracts that were not deployed from the same factory. 431 | * @dev User specifies maximum input && exact output. 432 | * @param tokens_bought Amount of Tokens (token_addr) bought. 433 | * @param max_tokens_sold Maximum Tokens (token) sold. 434 | * @param max_eth_sold Maximum ETH purchased as intermediary. 435 | * @param deadline Time after which this transaction can no longer be executed. 436 | * @param exchange_addr The address of the exchange for the token being purchased. 437 | * @return Amount of Tokens (token) sold. 438 | */ 439 | function tokenToExchangeSwapOutput( 440 | uint256 tokens_bought, 441 | uint256 max_tokens_sold, 442 | uint256 max_eth_sold, 443 | uint256 deadline, 444 | address payable exchange_addr) 445 | public returns (uint256) 446 | { 447 | return tokenToTokenOutput(tokens_bought, max_tokens_sold, max_eth_sold, deadline, msg.sender, msg.sender, exchange_addr); 448 | } 449 | 450 | /** 451 | * @notice Convert Tokens (token) to Tokens (exchange_addr.token) && transfers 452 | * Tokens (exchange_addr.token) to recipient. 453 | * @dev Allows trades through contracts that were not deployed from the same factory. 454 | * @dev User specifies maximum input && exact output. 455 | * @param tokens_bought Amount of Tokens (token_addr) bought. 456 | * @param max_tokens_sold Maximum Tokens (token) sold. 457 | * @param max_eth_sold Maximum ETH purchased as intermediary. 458 | * @param deadline Time after which this transaction can no longer be executed. 459 | * @param recipient The address that receives output ETH. 460 | * @param exchange_addr The address of the exchange for the token being purchased. 461 | * @return Amount of Tokens (token) sold. 462 | */ 463 | function tokenToExchangeTransferOutput( 464 | uint256 tokens_bought, 465 | uint256 max_tokens_sold, 466 | uint256 max_eth_sold, 467 | uint256 deadline, 468 | address recipient, 469 | address payable exchange_addr) 470 | public returns (uint256) 471 | { 472 | require(recipient != address(this)); 473 | return tokenToTokenOutput(tokens_bought, max_tokens_sold, max_eth_sold, deadline, msg.sender, recipient, exchange_addr); 474 | } 475 | 476 | 477 | /***********************************| 478 | | Getter Functions | 479 | |__________________________________*/ 480 | 481 | /** 482 | * @notice Public price function for ETH to Token trades with an exact input. 483 | * @param eth_sold Amount of ETH sold. 484 | * @return Amount of Tokens that can be bought with input ETH. 485 | */ 486 | function getEthToTokenInputPrice(uint256 eth_sold) public view returns (uint256) { 487 | require(eth_sold > 0); 488 | uint256 token_reserve = token.balanceOf(address(this)); 489 | return getInputPrice(eth_sold, address(this).balance, token_reserve); 490 | } 491 | 492 | /** 493 | * @notice Public price function for ETH to Token trades with an exact output. 494 | * @param tokens_bought Amount of Tokens bought. 495 | * @return Amount of ETH needed to buy output Tokens. 496 | */ 497 | function getEthToTokenOutputPrice(uint256 tokens_bought) public view returns (uint256) { 498 | require(tokens_bought > 0); 499 | uint256 token_reserve = token.balanceOf(address(this)); 500 | uint256 eth_sold = getOutputPrice(tokens_bought, address(this).balance, token_reserve); 501 | return eth_sold; 502 | } 503 | 504 | /** 505 | * @notice Public price function for Token to ETH trades with an exact input. 506 | * @param tokens_sold Amount of Tokens sold. 507 | * @return Amount of ETH that can be bought with input Tokens. 508 | */ 509 | function getTokenToEthInputPrice(uint256 tokens_sold) public view returns (uint256) { 510 | require(tokens_sold > 0); 511 | uint256 token_reserve = token.balanceOf(address(this)); 512 | uint256 eth_bought = getInputPrice(tokens_sold, token_reserve, address(this).balance); 513 | return eth_bought; 514 | } 515 | 516 | /** 517 | * @notice Public price function for Token to ETH trades with an exact output. 518 | * @param eth_bought Amount of output ETH. 519 | * @return Amount of Tokens needed to buy output ETH. 520 | */ 521 | function getTokenToEthOutputPrice(uint256 eth_bought) public view returns (uint256) { 522 | require(eth_bought > 0); 523 | uint256 token_reserve = token.balanceOf(address(this)); 524 | return getOutputPrice(eth_bought, token_reserve, address(this).balance); 525 | } 526 | 527 | /** 528 | * @return Address of Token that is sold on this exchange. 529 | */ 530 | function tokenAddress() public view returns (address) { 531 | return address(token); 532 | } 533 | 534 | /** 535 | * @return Address of factory that created this exchange. 536 | */ 537 | function factoryAddress() public view returns (address) { 538 | return address(factory); 539 | } 540 | 541 | 542 | /***********************************| 543 | | Liquidity Functions | 544 | |__________________________________*/ 545 | 546 | /** 547 | * @notice Deposit ETH && Tokens (token) at current ratio to mint UNI tokens. 548 | * @dev min_liquidity does nothing when total UNI supply is 0. 549 | * @param min_liquidity Minimum number of UNI sender will mint if total UNI supply is greater than 0. 550 | * @param max_tokens Maximum number of tokens deposited. Deposits max amount if total UNI supply is 0. 551 | * @param deadline Time after which this transaction can no longer be executed. 552 | * @return The amount of UNI minted. 553 | */ 554 | function addLiquidity(uint256 min_liquidity, uint256 max_tokens, uint256 deadline) public payable returns (uint256) { 555 | require(deadline > block.timestamp && max_tokens > 0 && msg.value > 0, 'UniswapExchange#addLiquidity: INVALID_ARGUMENT'); 556 | uint256 total_liquidity = _totalSupply; 557 | 558 | if (total_liquidity > 0) { 559 | require(min_liquidity > 0); 560 | uint256 eth_reserve = address(this).balance.sub(msg.value); 561 | uint256 token_reserve = token.balanceOf(address(this)); 562 | uint256 token_amount = (msg.value.mul(token_reserve) / eth_reserve).add(1); 563 | uint256 liquidity_minted = msg.value.mul(total_liquidity) / eth_reserve; 564 | require(max_tokens >= token_amount && liquidity_minted >= min_liquidity); 565 | _balances[msg.sender] = _balances[msg.sender].add(liquidity_minted); 566 | _totalSupply = total_liquidity.add(liquidity_minted); 567 | require(token.transferFrom(msg.sender, address(this), token_amount)); 568 | emit AddLiquidity(msg.sender, msg.value, token_amount); 569 | emit Transfer(address(0), msg.sender, liquidity_minted); 570 | return liquidity_minted; 571 | 572 | } else { 573 | require(address(factory) != address(0) && address(token) != address(0) && msg.value >= 1000000000, "INVALID_VALUE"); 574 | require(factory.getExchange(address(token)) == address(this)); 575 | uint256 token_amount = max_tokens; 576 | uint256 initial_liquidity = address(this).balance; 577 | _totalSupply = initial_liquidity; 578 | _balances[msg.sender] = initial_liquidity; 579 | require(token.transferFrom(msg.sender, address(this), token_amount)); 580 | emit AddLiquidity(msg.sender, msg.value, token_amount); 581 | emit Transfer(address(0), msg.sender, initial_liquidity); 582 | return initial_liquidity; 583 | } 584 | } 585 | 586 | /** 587 | * @dev Burn UNI tokens to withdraw ETH && Tokens at current ratio. 588 | * @param amount Amount of UNI burned. 589 | * @param min_eth Minimum ETH withdrawn. 590 | * @param min_tokens Minimum Tokens withdrawn. 591 | * @param deadline Time after which this transaction can no longer be executed. 592 | * @return The amount of ETH && Tokens withdrawn. 593 | */ 594 | function removeLiquidity(uint256 amount, uint256 min_eth, uint256 min_tokens, uint256 deadline) public returns (uint256, uint256) { 595 | require(amount > 0 && deadline > block.timestamp && min_eth > 0 && min_tokens > 0); 596 | uint256 total_liquidity = _totalSupply; 597 | require(total_liquidity > 0); 598 | uint256 token_reserve = token.balanceOf(address(this)); 599 | uint256 eth_amount = amount.mul(address(this).balance) / total_liquidity; 600 | uint256 token_amount = amount.mul(token_reserve) / total_liquidity; 601 | require(eth_amount >= min_eth && token_amount >= min_tokens); 602 | 603 | _balances[msg.sender] = _balances[msg.sender].sub(amount); 604 | _totalSupply = total_liquidity.sub(amount); 605 | msg.sender.transfer(eth_amount); 606 | require(token.transfer(msg.sender, token_amount)); 607 | emit RemoveLiquidity(msg.sender, eth_amount, token_amount); 608 | emit Transfer(msg.sender, address(0), amount); 609 | return (eth_amount, token_amount); 610 | } 611 | 612 | 613 | } 614 | -------------------------------------------------------------------------------- /abis/UniswapExchange.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": true, 7 | "internalType": "address", 8 | "name": "provider", 9 | "type": "address" 10 | }, 11 | { 12 | "indexed": true, 13 | "internalType": "uint256", 14 | "name": "eth_amount", 15 | "type": "uint256" 16 | }, 17 | { 18 | "indexed": true, 19 | "internalType": "uint256", 20 | "name": "token_amount", 21 | "type": "uint256" 22 | } 23 | ], 24 | "name": "AddLiquidity", 25 | "type": "event" 26 | }, 27 | { 28 | "anonymous": false, 29 | "inputs": [ 30 | { 31 | "indexed": true, 32 | "internalType": "address", 33 | "name": "owner", 34 | "type": "address" 35 | }, 36 | { 37 | "indexed": true, 38 | "internalType": "address", 39 | "name": "spender", 40 | "type": "address" 41 | }, 42 | { 43 | "indexed": false, 44 | "internalType": "uint256", 45 | "name": "value", 46 | "type": "uint256" 47 | } 48 | ], 49 | "name": "Approval", 50 | "type": "event" 51 | }, 52 | { 53 | "anonymous": false, 54 | "inputs": [ 55 | { 56 | "indexed": true, 57 | "internalType": "address", 58 | "name": "buyer", 59 | "type": "address" 60 | }, 61 | { 62 | "indexed": true, 63 | "internalType": "uint256", 64 | "name": "tokens_sold", 65 | "type": "uint256" 66 | }, 67 | { 68 | "indexed": true, 69 | "internalType": "uint256", 70 | "name": "eth_bought", 71 | "type": "uint256" 72 | } 73 | ], 74 | "name": "EthPurchase", 75 | "type": "event" 76 | }, 77 | { 78 | "anonymous": false, 79 | "inputs": [ 80 | { 81 | "indexed": true, 82 | "internalType": "address", 83 | "name": "provider", 84 | "type": "address" 85 | }, 86 | { 87 | "indexed": true, 88 | "internalType": "uint256", 89 | "name": "eth_amount", 90 | "type": "uint256" 91 | }, 92 | { 93 | "indexed": true, 94 | "internalType": "uint256", 95 | "name": "token_amount", 96 | "type": "uint256" 97 | } 98 | ], 99 | "name": "RemoveLiquidity", 100 | "type": "event" 101 | }, 102 | { 103 | "anonymous": false, 104 | "inputs": [ 105 | { 106 | "indexed": true, 107 | "internalType": "address", 108 | "name": "buyer", 109 | "type": "address" 110 | }, 111 | { 112 | "indexed": true, 113 | "internalType": "uint256", 114 | "name": "eth_sold", 115 | "type": "uint256" 116 | }, 117 | { 118 | "indexed": true, 119 | "internalType": "uint256", 120 | "name": "tokens_bought", 121 | "type": "uint256" 122 | } 123 | ], 124 | "name": "TokenPurchase", 125 | "type": "event" 126 | }, 127 | { 128 | "anonymous": false, 129 | "inputs": [ 130 | { 131 | "indexed": true, 132 | "internalType": "address", 133 | "name": "from", 134 | "type": "address" 135 | }, 136 | { 137 | "indexed": true, 138 | "internalType": "address", 139 | "name": "to", 140 | "type": "address" 141 | }, 142 | { 143 | "indexed": false, 144 | "internalType": "uint256", 145 | "name": "value", 146 | "type": "uint256" 147 | } 148 | ], 149 | "name": "Transfer", 150 | "type": "event" 151 | }, 152 | { 153 | "payable": true, 154 | "stateMutability": "payable", 155 | "type": "fallback" 156 | }, 157 | { 158 | "constant": true, 159 | "inputs": [ 160 | { 161 | "internalType": "address", 162 | "name": "owner", 163 | "type": "address" 164 | }, 165 | { 166 | "internalType": "address", 167 | "name": "spender", 168 | "type": "address" 169 | } 170 | ], 171 | "name": "allowance", 172 | "outputs": [ 173 | { 174 | "internalType": "uint256", 175 | "name": "", 176 | "type": "uint256" 177 | } 178 | ], 179 | "payable": false, 180 | "stateMutability": "view", 181 | "type": "function" 182 | }, 183 | { 184 | "constant": false, 185 | "inputs": [ 186 | { 187 | "internalType": "address", 188 | "name": "spender", 189 | "type": "address" 190 | }, 191 | { 192 | "internalType": "uint256", 193 | "name": "value", 194 | "type": "uint256" 195 | } 196 | ], 197 | "name": "approve", 198 | "outputs": [ 199 | { 200 | "internalType": "bool", 201 | "name": "", 202 | "type": "bool" 203 | } 204 | ], 205 | "payable": false, 206 | "stateMutability": "nonpayable", 207 | "type": "function" 208 | }, 209 | { 210 | "constant": true, 211 | "inputs": [ 212 | { 213 | "internalType": "address", 214 | "name": "owner", 215 | "type": "address" 216 | } 217 | ], 218 | "name": "balanceOf", 219 | "outputs": [ 220 | { 221 | "internalType": "uint256", 222 | "name": "", 223 | "type": "uint256" 224 | } 225 | ], 226 | "payable": false, 227 | "stateMutability": "view", 228 | "type": "function" 229 | }, 230 | { 231 | "constant": true, 232 | "inputs": [], 233 | "name": "decimals", 234 | "outputs": [ 235 | { 236 | "internalType": "uint256", 237 | "name": "", 238 | "type": "uint256" 239 | } 240 | ], 241 | "payable": false, 242 | "stateMutability": "view", 243 | "type": "function" 244 | }, 245 | { 246 | "constant": false, 247 | "inputs": [ 248 | { 249 | "internalType": "address", 250 | "name": "spender", 251 | "type": "address" 252 | }, 253 | { 254 | "internalType": "uint256", 255 | "name": "subtractedValue", 256 | "type": "uint256" 257 | } 258 | ], 259 | "name": "decreaseAllowance", 260 | "outputs": [ 261 | { 262 | "internalType": "bool", 263 | "name": "", 264 | "type": "bool" 265 | } 266 | ], 267 | "payable": false, 268 | "stateMutability": "nonpayable", 269 | "type": "function" 270 | }, 271 | { 272 | "constant": false, 273 | "inputs": [ 274 | { 275 | "internalType": "address", 276 | "name": "spender", 277 | "type": "address" 278 | }, 279 | { 280 | "internalType": "uint256", 281 | "name": "addedValue", 282 | "type": "uint256" 283 | } 284 | ], 285 | "name": "increaseAllowance", 286 | "outputs": [ 287 | { 288 | "internalType": "bool", 289 | "name": "", 290 | "type": "bool" 291 | } 292 | ], 293 | "payable": false, 294 | "stateMutability": "nonpayable", 295 | "type": "function" 296 | }, 297 | { 298 | "constant": true, 299 | "inputs": [], 300 | "name": "name", 301 | "outputs": [ 302 | { 303 | "internalType": "bytes32", 304 | "name": "", 305 | "type": "bytes32" 306 | } 307 | ], 308 | "payable": false, 309 | "stateMutability": "view", 310 | "type": "function" 311 | }, 312 | { 313 | "constant": true, 314 | "inputs": [], 315 | "name": "symbol", 316 | "outputs": [ 317 | { 318 | "internalType": "bytes32", 319 | "name": "", 320 | "type": "bytes32" 321 | } 322 | ], 323 | "payable": false, 324 | "stateMutability": "view", 325 | "type": "function" 326 | }, 327 | { 328 | "constant": true, 329 | "inputs": [], 330 | "name": "totalSupply", 331 | "outputs": [ 332 | { 333 | "internalType": "uint256", 334 | "name": "", 335 | "type": "uint256" 336 | } 337 | ], 338 | "payable": false, 339 | "stateMutability": "view", 340 | "type": "function" 341 | }, 342 | { 343 | "constant": false, 344 | "inputs": [ 345 | { 346 | "internalType": "address", 347 | "name": "to", 348 | "type": "address" 349 | }, 350 | { 351 | "internalType": "uint256", 352 | "name": "value", 353 | "type": "uint256" 354 | } 355 | ], 356 | "name": "transfer", 357 | "outputs": [ 358 | { 359 | "internalType": "bool", 360 | "name": "", 361 | "type": "bool" 362 | } 363 | ], 364 | "payable": false, 365 | "stateMutability": "nonpayable", 366 | "type": "function" 367 | }, 368 | { 369 | "constant": false, 370 | "inputs": [ 371 | { 372 | "internalType": "address", 373 | "name": "from", 374 | "type": "address" 375 | }, 376 | { 377 | "internalType": "address", 378 | "name": "to", 379 | "type": "address" 380 | }, 381 | { 382 | "internalType": "uint256", 383 | "name": "value", 384 | "type": "uint256" 385 | } 386 | ], 387 | "name": "transferFrom", 388 | "outputs": [ 389 | { 390 | "internalType": "bool", 391 | "name": "", 392 | "type": "bool" 393 | } 394 | ], 395 | "payable": false, 396 | "stateMutability": "nonpayable", 397 | "type": "function" 398 | }, 399 | { 400 | "constant": false, 401 | "inputs": [ 402 | { 403 | "internalType": "address", 404 | "name": "token_addr", 405 | "type": "address" 406 | } 407 | ], 408 | "name": "setup", 409 | "outputs": [], 410 | "payable": false, 411 | "stateMutability": "nonpayable", 412 | "type": "function" 413 | }, 414 | { 415 | "constant": true, 416 | "inputs": [ 417 | { 418 | "internalType": "uint256", 419 | "name": "input_amount", 420 | "type": "uint256" 421 | }, 422 | { 423 | "internalType": "uint256", 424 | "name": "input_reserve", 425 | "type": "uint256" 426 | }, 427 | { 428 | "internalType": "uint256", 429 | "name": "output_reserve", 430 | "type": "uint256" 431 | } 432 | ], 433 | "name": "getInputPrice", 434 | "outputs": [ 435 | { 436 | "internalType": "uint256", 437 | "name": "", 438 | "type": "uint256" 439 | } 440 | ], 441 | "payable": false, 442 | "stateMutability": "view", 443 | "type": "function" 444 | }, 445 | { 446 | "constant": true, 447 | "inputs": [ 448 | { 449 | "internalType": "uint256", 450 | "name": "output_amount", 451 | "type": "uint256" 452 | }, 453 | { 454 | "internalType": "uint256", 455 | "name": "input_reserve", 456 | "type": "uint256" 457 | }, 458 | { 459 | "internalType": "uint256", 460 | "name": "output_reserve", 461 | "type": "uint256" 462 | } 463 | ], 464 | "name": "getOutputPrice", 465 | "outputs": [ 466 | { 467 | "internalType": "uint256", 468 | "name": "", 469 | "type": "uint256" 470 | } 471 | ], 472 | "payable": false, 473 | "stateMutability": "view", 474 | "type": "function" 475 | }, 476 | { 477 | "constant": false, 478 | "inputs": [ 479 | { 480 | "internalType": "uint256", 481 | "name": "min_tokens", 482 | "type": "uint256" 483 | }, 484 | { 485 | "internalType": "uint256", 486 | "name": "deadline", 487 | "type": "uint256" 488 | } 489 | ], 490 | "name": "ethToTokenSwapInput", 491 | "outputs": [ 492 | { 493 | "internalType": "uint256", 494 | "name": "", 495 | "type": "uint256" 496 | } 497 | ], 498 | "payable": true, 499 | "stateMutability": "payable", 500 | "type": "function" 501 | }, 502 | { 503 | "constant": false, 504 | "inputs": [ 505 | { 506 | "internalType": "uint256", 507 | "name": "min_tokens", 508 | "type": "uint256" 509 | }, 510 | { 511 | "internalType": "uint256", 512 | "name": "deadline", 513 | "type": "uint256" 514 | }, 515 | { 516 | "internalType": "address", 517 | "name": "recipient", 518 | "type": "address" 519 | } 520 | ], 521 | "name": "ethToTokenTransferInput", 522 | "outputs": [ 523 | { 524 | "internalType": "uint256", 525 | "name": "", 526 | "type": "uint256" 527 | } 528 | ], 529 | "payable": true, 530 | "stateMutability": "payable", 531 | "type": "function" 532 | }, 533 | { 534 | "constant": false, 535 | "inputs": [ 536 | { 537 | "internalType": "uint256", 538 | "name": "tokens_bought", 539 | "type": "uint256" 540 | }, 541 | { 542 | "internalType": "uint256", 543 | "name": "deadline", 544 | "type": "uint256" 545 | } 546 | ], 547 | "name": "ethToTokenSwapOutput", 548 | "outputs": [ 549 | { 550 | "internalType": "uint256", 551 | "name": "", 552 | "type": "uint256" 553 | } 554 | ], 555 | "payable": true, 556 | "stateMutability": "payable", 557 | "type": "function" 558 | }, 559 | { 560 | "constant": false, 561 | "inputs": [ 562 | { 563 | "internalType": "uint256", 564 | "name": "tokens_bought", 565 | "type": "uint256" 566 | }, 567 | { 568 | "internalType": "uint256", 569 | "name": "deadline", 570 | "type": "uint256" 571 | }, 572 | { 573 | "internalType": "address", 574 | "name": "recipient", 575 | "type": "address" 576 | } 577 | ], 578 | "name": "ethToTokenTransferOutput", 579 | "outputs": [ 580 | { 581 | "internalType": "uint256", 582 | "name": "", 583 | "type": "uint256" 584 | } 585 | ], 586 | "payable": true, 587 | "stateMutability": "payable", 588 | "type": "function" 589 | }, 590 | { 591 | "constant": false, 592 | "inputs": [ 593 | { 594 | "internalType": "uint256", 595 | "name": "tokens_sold", 596 | "type": "uint256" 597 | }, 598 | { 599 | "internalType": "uint256", 600 | "name": "min_eth", 601 | "type": "uint256" 602 | }, 603 | { 604 | "internalType": "uint256", 605 | "name": "deadline", 606 | "type": "uint256" 607 | } 608 | ], 609 | "name": "tokenToEthSwapInput", 610 | "outputs": [ 611 | { 612 | "internalType": "uint256", 613 | "name": "", 614 | "type": "uint256" 615 | } 616 | ], 617 | "payable": false, 618 | "stateMutability": "nonpayable", 619 | "type": "function" 620 | }, 621 | { 622 | "constant": false, 623 | "inputs": [ 624 | { 625 | "internalType": "uint256", 626 | "name": "tokens_sold", 627 | "type": "uint256" 628 | }, 629 | { 630 | "internalType": "uint256", 631 | "name": "min_eth", 632 | "type": "uint256" 633 | }, 634 | { 635 | "internalType": "uint256", 636 | "name": "deadline", 637 | "type": "uint256" 638 | }, 639 | { 640 | "internalType": "address payable", 641 | "name": "recipient", 642 | "type": "address" 643 | } 644 | ], 645 | "name": "tokenToEthTransferInput", 646 | "outputs": [ 647 | { 648 | "internalType": "uint256", 649 | "name": "", 650 | "type": "uint256" 651 | } 652 | ], 653 | "payable": false, 654 | "stateMutability": "nonpayable", 655 | "type": "function" 656 | }, 657 | { 658 | "constant": false, 659 | "inputs": [ 660 | { 661 | "internalType": "uint256", 662 | "name": "eth_bought", 663 | "type": "uint256" 664 | }, 665 | { 666 | "internalType": "uint256", 667 | "name": "max_tokens", 668 | "type": "uint256" 669 | }, 670 | { 671 | "internalType": "uint256", 672 | "name": "deadline", 673 | "type": "uint256" 674 | } 675 | ], 676 | "name": "tokenToEthSwapOutput", 677 | "outputs": [ 678 | { 679 | "internalType": "uint256", 680 | "name": "", 681 | "type": "uint256" 682 | } 683 | ], 684 | "payable": false, 685 | "stateMutability": "nonpayable", 686 | "type": "function" 687 | }, 688 | { 689 | "constant": false, 690 | "inputs": [ 691 | { 692 | "internalType": "uint256", 693 | "name": "eth_bought", 694 | "type": "uint256" 695 | }, 696 | { 697 | "internalType": "uint256", 698 | "name": "max_tokens", 699 | "type": "uint256" 700 | }, 701 | { 702 | "internalType": "uint256", 703 | "name": "deadline", 704 | "type": "uint256" 705 | }, 706 | { 707 | "internalType": "address payable", 708 | "name": "recipient", 709 | "type": "address" 710 | } 711 | ], 712 | "name": "tokenToEthTransferOutput", 713 | "outputs": [ 714 | { 715 | "internalType": "uint256", 716 | "name": "", 717 | "type": "uint256" 718 | } 719 | ], 720 | "payable": false, 721 | "stateMutability": "nonpayable", 722 | "type": "function" 723 | }, 724 | { 725 | "constant": false, 726 | "inputs": [ 727 | { 728 | "internalType": "uint256", 729 | "name": "tokens_sold", 730 | "type": "uint256" 731 | }, 732 | { 733 | "internalType": "uint256", 734 | "name": "min_tokens_bought", 735 | "type": "uint256" 736 | }, 737 | { 738 | "internalType": "uint256", 739 | "name": "min_eth_bought", 740 | "type": "uint256" 741 | }, 742 | { 743 | "internalType": "uint256", 744 | "name": "deadline", 745 | "type": "uint256" 746 | }, 747 | { 748 | "internalType": "address", 749 | "name": "token_addr", 750 | "type": "address" 751 | } 752 | ], 753 | "name": "tokenToTokenSwapInput", 754 | "outputs": [ 755 | { 756 | "internalType": "uint256", 757 | "name": "", 758 | "type": "uint256" 759 | } 760 | ], 761 | "payable": false, 762 | "stateMutability": "nonpayable", 763 | "type": "function" 764 | }, 765 | { 766 | "constant": false, 767 | "inputs": [ 768 | { 769 | "internalType": "uint256", 770 | "name": "tokens_sold", 771 | "type": "uint256" 772 | }, 773 | { 774 | "internalType": "uint256", 775 | "name": "min_tokens_bought", 776 | "type": "uint256" 777 | }, 778 | { 779 | "internalType": "uint256", 780 | "name": "min_eth_bought", 781 | "type": "uint256" 782 | }, 783 | { 784 | "internalType": "uint256", 785 | "name": "deadline", 786 | "type": "uint256" 787 | }, 788 | { 789 | "internalType": "address", 790 | "name": "recipient", 791 | "type": "address" 792 | }, 793 | { 794 | "internalType": "address", 795 | "name": "token_addr", 796 | "type": "address" 797 | } 798 | ], 799 | "name": "tokenToTokenTransferInput", 800 | "outputs": [ 801 | { 802 | "internalType": "uint256", 803 | "name": "", 804 | "type": "uint256" 805 | } 806 | ], 807 | "payable": false, 808 | "stateMutability": "nonpayable", 809 | "type": "function" 810 | }, 811 | { 812 | "constant": false, 813 | "inputs": [ 814 | { 815 | "internalType": "uint256", 816 | "name": "tokens_bought", 817 | "type": "uint256" 818 | }, 819 | { 820 | "internalType": "uint256", 821 | "name": "max_tokens_sold", 822 | "type": "uint256" 823 | }, 824 | { 825 | "internalType": "uint256", 826 | "name": "max_eth_sold", 827 | "type": "uint256" 828 | }, 829 | { 830 | "internalType": "uint256", 831 | "name": "deadline", 832 | "type": "uint256" 833 | }, 834 | { 835 | "internalType": "address", 836 | "name": "token_addr", 837 | "type": "address" 838 | } 839 | ], 840 | "name": "tokenToTokenSwapOutput", 841 | "outputs": [ 842 | { 843 | "internalType": "uint256", 844 | "name": "", 845 | "type": "uint256" 846 | } 847 | ], 848 | "payable": false, 849 | "stateMutability": "nonpayable", 850 | "type": "function" 851 | }, 852 | { 853 | "constant": false, 854 | "inputs": [ 855 | { 856 | "internalType": "uint256", 857 | "name": "tokens_bought", 858 | "type": "uint256" 859 | }, 860 | { 861 | "internalType": "uint256", 862 | "name": "max_tokens_sold", 863 | "type": "uint256" 864 | }, 865 | { 866 | "internalType": "uint256", 867 | "name": "max_eth_sold", 868 | "type": "uint256" 869 | }, 870 | { 871 | "internalType": "uint256", 872 | "name": "deadline", 873 | "type": "uint256" 874 | }, 875 | { 876 | "internalType": "address", 877 | "name": "recipient", 878 | "type": "address" 879 | }, 880 | { 881 | "internalType": "address", 882 | "name": "token_addr", 883 | "type": "address" 884 | } 885 | ], 886 | "name": "tokenToTokenTransferOutput", 887 | "outputs": [ 888 | { 889 | "internalType": "uint256", 890 | "name": "", 891 | "type": "uint256" 892 | } 893 | ], 894 | "payable": false, 895 | "stateMutability": "nonpayable", 896 | "type": "function" 897 | }, 898 | { 899 | "constant": false, 900 | "inputs": [ 901 | { 902 | "internalType": "uint256", 903 | "name": "tokens_sold", 904 | "type": "uint256" 905 | }, 906 | { 907 | "internalType": "uint256", 908 | "name": "min_tokens_bought", 909 | "type": "uint256" 910 | }, 911 | { 912 | "internalType": "uint256", 913 | "name": "min_eth_bought", 914 | "type": "uint256" 915 | }, 916 | { 917 | "internalType": "uint256", 918 | "name": "deadline", 919 | "type": "uint256" 920 | }, 921 | { 922 | "internalType": "address payable", 923 | "name": "exchange_addr", 924 | "type": "address" 925 | } 926 | ], 927 | "name": "tokenToExchangeSwapInput", 928 | "outputs": [ 929 | { 930 | "internalType": "uint256", 931 | "name": "", 932 | "type": "uint256" 933 | } 934 | ], 935 | "payable": false, 936 | "stateMutability": "nonpayable", 937 | "type": "function" 938 | }, 939 | { 940 | "constant": false, 941 | "inputs": [ 942 | { 943 | "internalType": "uint256", 944 | "name": "tokens_sold", 945 | "type": "uint256" 946 | }, 947 | { 948 | "internalType": "uint256", 949 | "name": "min_tokens_bought", 950 | "type": "uint256" 951 | }, 952 | { 953 | "internalType": "uint256", 954 | "name": "min_eth_bought", 955 | "type": "uint256" 956 | }, 957 | { 958 | "internalType": "uint256", 959 | "name": "deadline", 960 | "type": "uint256" 961 | }, 962 | { 963 | "internalType": "address", 964 | "name": "recipient", 965 | "type": "address" 966 | }, 967 | { 968 | "internalType": "address payable", 969 | "name": "exchange_addr", 970 | "type": "address" 971 | } 972 | ], 973 | "name": "tokenToExchangeTransferInput", 974 | "outputs": [ 975 | { 976 | "internalType": "uint256", 977 | "name": "", 978 | "type": "uint256" 979 | } 980 | ], 981 | "payable": false, 982 | "stateMutability": "nonpayable", 983 | "type": "function" 984 | }, 985 | { 986 | "constant": false, 987 | "inputs": [ 988 | { 989 | "internalType": "uint256", 990 | "name": "tokens_bought", 991 | "type": "uint256" 992 | }, 993 | { 994 | "internalType": "uint256", 995 | "name": "max_tokens_sold", 996 | "type": "uint256" 997 | }, 998 | { 999 | "internalType": "uint256", 1000 | "name": "max_eth_sold", 1001 | "type": "uint256" 1002 | }, 1003 | { 1004 | "internalType": "uint256", 1005 | "name": "deadline", 1006 | "type": "uint256" 1007 | }, 1008 | { 1009 | "internalType": "address payable", 1010 | "name": "exchange_addr", 1011 | "type": "address" 1012 | } 1013 | ], 1014 | "name": "tokenToExchangeSwapOutput", 1015 | "outputs": [ 1016 | { 1017 | "internalType": "uint256", 1018 | "name": "", 1019 | "type": "uint256" 1020 | } 1021 | ], 1022 | "payable": false, 1023 | "stateMutability": "nonpayable", 1024 | "type": "function" 1025 | }, 1026 | { 1027 | "constant": false, 1028 | "inputs": [ 1029 | { 1030 | "internalType": "uint256", 1031 | "name": "tokens_bought", 1032 | "type": "uint256" 1033 | }, 1034 | { 1035 | "internalType": "uint256", 1036 | "name": "max_tokens_sold", 1037 | "type": "uint256" 1038 | }, 1039 | { 1040 | "internalType": "uint256", 1041 | "name": "max_eth_sold", 1042 | "type": "uint256" 1043 | }, 1044 | { 1045 | "internalType": "uint256", 1046 | "name": "deadline", 1047 | "type": "uint256" 1048 | }, 1049 | { 1050 | "internalType": "address", 1051 | "name": "recipient", 1052 | "type": "address" 1053 | }, 1054 | { 1055 | "internalType": "address payable", 1056 | "name": "exchange_addr", 1057 | "type": "address" 1058 | } 1059 | ], 1060 | "name": "tokenToExchangeTransferOutput", 1061 | "outputs": [ 1062 | { 1063 | "internalType": "uint256", 1064 | "name": "", 1065 | "type": "uint256" 1066 | } 1067 | ], 1068 | "payable": false, 1069 | "stateMutability": "nonpayable", 1070 | "type": "function" 1071 | }, 1072 | { 1073 | "constant": true, 1074 | "inputs": [ 1075 | { 1076 | "internalType": "uint256", 1077 | "name": "eth_sold", 1078 | "type": "uint256" 1079 | } 1080 | ], 1081 | "name": "getEthToTokenInputPrice", 1082 | "outputs": [ 1083 | { 1084 | "internalType": "uint256", 1085 | "name": "", 1086 | "type": "uint256" 1087 | } 1088 | ], 1089 | "payable": false, 1090 | "stateMutability": "view", 1091 | "type": "function" 1092 | }, 1093 | { 1094 | "constant": true, 1095 | "inputs": [ 1096 | { 1097 | "internalType": "uint256", 1098 | "name": "tokens_bought", 1099 | "type": "uint256" 1100 | } 1101 | ], 1102 | "name": "getEthToTokenOutputPrice", 1103 | "outputs": [ 1104 | { 1105 | "internalType": "uint256", 1106 | "name": "", 1107 | "type": "uint256" 1108 | } 1109 | ], 1110 | "payable": false, 1111 | "stateMutability": "view", 1112 | "type": "function" 1113 | }, 1114 | { 1115 | "constant": true, 1116 | "inputs": [ 1117 | { 1118 | "internalType": "uint256", 1119 | "name": "tokens_sold", 1120 | "type": "uint256" 1121 | } 1122 | ], 1123 | "name": "getTokenToEthInputPrice", 1124 | "outputs": [ 1125 | { 1126 | "internalType": "uint256", 1127 | "name": "", 1128 | "type": "uint256" 1129 | } 1130 | ], 1131 | "payable": false, 1132 | "stateMutability": "view", 1133 | "type": "function" 1134 | }, 1135 | { 1136 | "constant": true, 1137 | "inputs": [ 1138 | { 1139 | "internalType": "uint256", 1140 | "name": "eth_bought", 1141 | "type": "uint256" 1142 | } 1143 | ], 1144 | "name": "getTokenToEthOutputPrice", 1145 | "outputs": [ 1146 | { 1147 | "internalType": "uint256", 1148 | "name": "", 1149 | "type": "uint256" 1150 | } 1151 | ], 1152 | "payable": false, 1153 | "stateMutability": "view", 1154 | "type": "function" 1155 | }, 1156 | { 1157 | "constant": true, 1158 | "inputs": [], 1159 | "name": "tokenAddress", 1160 | "outputs": [ 1161 | { 1162 | "internalType": "address", 1163 | "name": "", 1164 | "type": "address" 1165 | } 1166 | ], 1167 | "payable": false, 1168 | "stateMutability": "view", 1169 | "type": "function" 1170 | }, 1171 | { 1172 | "constant": true, 1173 | "inputs": [], 1174 | "name": "factoryAddress", 1175 | "outputs": [ 1176 | { 1177 | "internalType": "address", 1178 | "name": "", 1179 | "type": "address" 1180 | } 1181 | ], 1182 | "payable": false, 1183 | "stateMutability": "view", 1184 | "type": "function" 1185 | }, 1186 | { 1187 | "constant": false, 1188 | "inputs": [ 1189 | { 1190 | "internalType": "uint256", 1191 | "name": "min_liquidity", 1192 | "type": "uint256" 1193 | }, 1194 | { 1195 | "internalType": "uint256", 1196 | "name": "max_tokens", 1197 | "type": "uint256" 1198 | }, 1199 | { 1200 | "internalType": "uint256", 1201 | "name": "deadline", 1202 | "type": "uint256" 1203 | } 1204 | ], 1205 | "name": "addLiquidity", 1206 | "outputs": [ 1207 | { 1208 | "internalType": "uint256", 1209 | "name": "", 1210 | "type": "uint256" 1211 | } 1212 | ], 1213 | "payable": true, 1214 | "stateMutability": "payable", 1215 | "type": "function" 1216 | }, 1217 | { 1218 | "constant": false, 1219 | "inputs": [ 1220 | { 1221 | "internalType": "uint256", 1222 | "name": "amount", 1223 | "type": "uint256" 1224 | }, 1225 | { 1226 | "internalType": "uint256", 1227 | "name": "min_eth", 1228 | "type": "uint256" 1229 | }, 1230 | { 1231 | "internalType": "uint256", 1232 | "name": "min_tokens", 1233 | "type": "uint256" 1234 | }, 1235 | { 1236 | "internalType": "uint256", 1237 | "name": "deadline", 1238 | "type": "uint256" 1239 | } 1240 | ], 1241 | "name": "removeLiquidity", 1242 | "outputs": [ 1243 | { 1244 | "internalType": "uint256", 1245 | "name": "", 1246 | "type": "uint256" 1247 | }, 1248 | { 1249 | "internalType": "uint256", 1250 | "name": "", 1251 | "type": "uint256" 1252 | } 1253 | ], 1254 | "payable": false, 1255 | "stateMutability": "nonpayable", 1256 | "type": "function" 1257 | } 1258 | ] 1259 | --------------------------------------------------------------------------------