// 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);
}