// SPDX-License-Identifier: GPL-3.0-or-later // This file is part of the http://github.com/aaronbloomfield/ccc repository, // and is released under the GPL 3.0 license. // x is the ether liquidity, with 18 decimals // y is the token liquidity, with a variable number of decimals // k = x * y, and will have somewhere around 30 decimals pragma solidity ^0.8.24; import "./IERC165.sol"; import "./IEtherPriceOracle.sol"; import "./IERC20Receiver.sol"; interface IDEX is IERC165, IERC20Receiver { //------------------------------------------------------------ // Events // This event must be emitted whenever the amount of liquidity // (either ether or token cryptocurrency) changes. This is from the // methods: createPool(), addLiquidity(), removeLiquidity() // receive(), and onERC20Received(). event liquidityChangeEvent(); //------------------------------------------------------------ // Getting the exchange rates and prices // How many decimals the token is shown to. This can just call the ERC-20 // contract to get that information, or you can save it in public // variable. As the other asset is ether, we know that is to 18 // decimals, and thus do not need a corresponding function for ether. function decimals() external view returns (uint); // Get the symbol of the ERC-20 cryptocurrency. This can just call the // ERC-20 contract to get that information, or you can save it in public // variable function symbol() external view returns (string memory); // Get the price of 1 ETH using the EtherPricer contract; return it in // cents. This just gets the price from the EtherPricer contract. function getEtherPrice() external view returns (uint); // Get the price of 1 Token using the EtherPricer contract; return it in // cents. This gets the price of ETH from the EtherPricer contract, and // then scales it -- based on the exchange ratio -- to determine the // price of the token cryptocurrency. function getTokenPrice() external view returns (uint); //------------------------------------------------------------ // Getting the liquidity of the pool or part thereof // Get the k value. If 100 ETH were added along with 1,000 of the token // cryptocurrency, and the former has 18 decimals and the latter 10 // decimals, then this will return 10^33. This can just be a public // variable. function k() external view returns (uint); // How much ether is in the pool; this can just be a public variable. This is // in wei, so 1.5 ETH -- which has 18 decimals -- would return // 1,500,000,000,000,000,000. This can just be a public variable. function x() external view returns (uint); // How many tokens are in the pool; this can just be a public variable. As // with the previous, this is returned with all the decimals. So 15 of // the token cryptocurrency coin, which has (say) 10 decimals, this would // return 150,000,000,000. This can just be a public variable. function y() external view returns (uint); // Get the amount of pool liquidity in USD (actually cents) using the // EtherPricer contract. We assume that the ETH and the token // cryptocurrency have the same value, and we know (from the EtherPricer // smart contract) how much the ETH is worth. function getPoolLiquidityInUSDCents() external view returns (uint); // How much ETH does the address have in the pool. This is the number in // wei. This can be just be a public mapping variable. function etherLiquidityForAddress(address who) external view returns (uint); // How much of the token cryptocurrency does the address have in the pool. // This is with however many decimals the token cryptocurrency has. This // can be just be a public mapping variable. function tokenLiquidityForAddress(address who) external view returns (uint); //------------------------------------------------------------ // Pool creation // This can be called exactly once, and creates the pool; only the // deployer of the contract call this. Some amount of ETH is passed in // along with this call. For purposes of this assignment, the ratio is // then defined based on the amount of ETH paid with this call and the // amount of the token cryptocurrency stated in the first parameter. The // first parameter is how many of the token cryptocurrency (with all the // decimals) to add to the pool; the ERC-20 contract that manages that // token cryptocurrency is the fourth parameter (the caller needs to // approve this contract for that much of the token cryptocurrency before // the call). The second and third parameters define the fraction -- // 0.1% would be 1 and 1000, for example. The last parameter is the // contract address of the EtherPricer contract being used, and can be // updated later via the setEtherPricer() function. function createPool(uint _tokenAmount, uint _feeNumerator, uint _feeDenominator, address _erc20token, address _etherPricer) external payable; //------------------------------------------------------------ // Fees // Get the numerator of the fee fraction; this can just be a public // variable. function feeNumerator() external view returns (uint); // Get the denominator of the fee fraction; this can just be a public // variable. function feeDenominator() external view returns (uint); // Get the amount of fees accumulated, in wei, for all addresses so far; this // can just be a public variable. function feesEther() external view returns (uint); // Get the amount of token fees accumulated for all addresses so far; this // can just be a public variable. This will have as many decimals as the // token cryptocurrency has. function feesToken() external view returns (uint); //------------------------------------------------------------ // Managing pool liquidity // Anybody can add liquidity to the pool. The amount of ETH is paid along // with the function call. The caller will have to approve the // appropriate amount of token cryptocurrency, via the ERC-20 contract, // for this call to complete successfully. Note that this function does // NOT remove any fees. function addLiquidity() external payable; // Remove liquidity -- both ether and token -- from the pool. The ETH is // paid to the caller, and the token cryptocurrency is transferred back // as well. If the parameter amount is more than the amount the address // has stored in the pool, this should revert. See the homework // description for how fees are managed and paid out, but note that this // function does NOT remove any fees. For this assignment, they cannot // take out more ether than they put in, and the amount of TCC that comes // with that cannot be more than they put in. If the exchange rates are // much different, this could cause issues, but we are not going to deal // with those issues in this assignment, so you can ignore factoring in // different exchange rates. function removeLiquidity(uint amountWei) external; //------------------------------------------------------------ // Exchanging currencies // Swaps ether for token. The amount of ETH is passed in as payment along // with this call. Note that the receive() function is of a special form, // and does not have the `function` keyword. receive() external payable; // Swap token for ether. The ERC-20 smart contract for the token // cryptocurrency must be approved to transfer that much into the DEX, // and the appropriate amount of ETH is paid back to the caller. // This function is defined in the IERC20Receiver.sol file // // function onERC20Received(address from, uint amount, address erc20) external returns (bool); //------------------------------------------------------------ // Functions for debugging and grading // This function allows changing of the contract that provides the current // ether price. function setEtherPricer(address p) external; // This gets the address of the etherPricer being used so that we can // verify we are using the correct one; this can just be a public variable. function etherPricer() external view returns (address); // Get the address of the ERC-20 token manager being used for the token // cryptocurrency; this can just be a public variable. function ERC20Address() external view returns (address); //------------------------------------------------------------ // Functions for efficiency // this function is just to lower the number of calls to the contract from // the dex.php web page; it just returns the information in many of the // above calls as a single call. The information it returns is a tuple // and is, in order: // // 0: the address of *this* DEX contract (address) // 1: token cryptocurrency abbreviation (string memory) // 2: token cryptocurrency name (string memory) // 3: ERC-20 token cryptocurrency address (address) // 4: k (uint) // 5: ether liquidity (uint) // 6: token liquidity (uint) // 7: fee numerator (uint) // 8: fee denominator (uint) // 9: token decimals (uint) // 10: fees collected in ether (uint) // 11: fees collected in the token CC (uint) function getDEXinfo() external view returns (address, string memory, string memory, address, uint, uint, uint, uint, uint, uint, uint, uint); //------------------------------------------------------------ // Functions for a future assignment // This should just revert. It is going to be used in the Arbitrage // assignment, so we are putting it into the interface now. function reset() external; //------------------------------------------------------------ // Inherited functions // From IERC165.sol; this contract supports three interfaces // function supportsInterface(bytes4 interfaceId) external view returns (bool); }