feat: finish challenge
Some checks failed
Lint / ci (lts/*, ubuntu-latest) (push) Has been cancelled
Some checks failed
Lint / ci (lts/*, ubuntu-latest) (push) Has been cancelled
This commit is contained in:
@@ -15,6 +15,8 @@ contract DEX {
|
||||
/* ========== GLOBAL VARIABLES ========== */
|
||||
|
||||
IERC20 token; //instantiates the imported contract
|
||||
uint256 public totalLiquidity;
|
||||
mapping (address => uint256) public liquidity;
|
||||
|
||||
/* ========== EVENTS ========== */
|
||||
|
||||
@@ -57,13 +59,27 @@ contract DEX {
|
||||
* @return totalLiquidity is the number of LPTs minting as a result of deposits made to DEX contract
|
||||
* NOTE: since ratio is 1:1, this is fine to initialize the totalLiquidity (wrt to balloons) as equal to eth balance of contract.
|
||||
*/
|
||||
function init(uint256 tokens) public payable returns (uint256) {}
|
||||
function init(uint256 tokens) public payable returns (uint256) {
|
||||
require(totalLiquidity == 0, "DEX: init - already has liquidity");
|
||||
totalLiquidity = address(this).balance;
|
||||
liquidity[msg.sender] = totalLiquidity;
|
||||
require(token.transferFrom(msg.sender, address(this), tokens), "DEX: init - transfer did not transact");
|
||||
return totalLiquidity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice returns yOutput, or yDelta for xInput (or xDelta)
|
||||
* @dev Follow along with the [original tutorial](https://medium.com/@austin_48503/%EF%B8%8F-minimum-viable-exchange-d84f30bd0c90) Price section for an understanding of the DEX's pricing model and for a price function to add to your contract. You may need to update the Solidity syntax (e.g. use + instead of .add, * instead of .mul, etc). Deploy when you are done.
|
||||
*/
|
||||
function price(uint256 xInput, uint256 xReserves, uint256 yReserves) public pure returns (uint256 yOutput) {}
|
||||
function price(uint256 xInput, uint256 xReserves, uint256 yReserves) public pure returns (uint256 yOutput) {
|
||||
uint256 feePercentage = 997;
|
||||
uint256 feeDenominator = 1000;
|
||||
uint256 xInputAfterFee = xInput * feePercentage;
|
||||
|
||||
uint256 numerator = xInputAfterFee * yReserves;
|
||||
uint256 denominator = (xReserves * feeDenominator) + xInputAfterFee;
|
||||
return (numerator / denominator);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice returns liquidity for a user.
|
||||
@@ -71,17 +87,41 @@ contract DEX {
|
||||
* NOTE: if you are using a mapping liquidity, then you can use `return liquidity[lp]` to get the liquidity for a user.
|
||||
* NOTE: if you will be submitting the challenge make sure to implement this function as it is used in the tests.
|
||||
*/
|
||||
function getLiquidity(address lp) public view returns (uint256) {}
|
||||
function getLiquidity(address lp) public view returns (uint256) {
|
||||
return liquidity[lp];
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice sends Ether to DEX in exchange for $BAL
|
||||
*/
|
||||
function ethToToken() public payable returns (uint256 tokenOutput) {}
|
||||
function ethToToken() public payable returns (uint256 tokenOutput) {
|
||||
require(msg.value > 0, "cannot swap 0 ETH");
|
||||
uint256 ethReserve = address(this).balance - msg.value;
|
||||
uint256 tokenReserve = token.balanceOf(address(this));
|
||||
tokenOutput = price(msg.value, ethReserve, tokenReserve);
|
||||
|
||||
require(token.transfer(msg.sender, tokenOutput), "ethToToken(): reverted swap.");
|
||||
emit EthToTokenSwap(msg.sender, tokenOutput, msg.value);
|
||||
return tokenOutput;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice sends $BAL tokens to DEX in exchange for Ether
|
||||
*/
|
||||
function tokenToEth(uint256 tokenInput) public returns (uint256 ethOutput) {}
|
||||
function tokenToEth(uint256 tokenInput) public returns (uint256 ethOutput) {
|
||||
require(tokenInput > 0, "cannot swap 0 tokens");
|
||||
require(token.balanceOf(msg.sender) >= tokenInput, "insufficient token balance");
|
||||
require(token.allowance(msg.sender, address(this)) >= tokenInput, "insufficient allowance");
|
||||
uint256 ethReserve = address(this).balance;
|
||||
uint256 tokenReserve = token.balanceOf(address(this));
|
||||
ethOutput = price(tokenInput, tokenReserve, ethReserve);
|
||||
|
||||
require(token.transferFrom(msg.sender, address(this), tokenInput), "tokenToEth(): reverted swap.");
|
||||
(bool success,) = msg.sender.call{value: ethOutput}("");
|
||||
require(success, "tokenToEth: reverted in transferring eth to you!");
|
||||
emit TokenToEthSwap(msg.sender, tokenInput, ethOutput);
|
||||
return ethOutput;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice allows deposits of $BAL and $ETH to liquidity pool
|
||||
@@ -89,11 +129,45 @@ contract DEX {
|
||||
* NOTE: user has to make sure to give DEX approval to spend their tokens on their behalf by calling approve function prior to this function call.
|
||||
* NOTE: Equal parts of both assets will be removed from the user's wallet with respect to the price outlined by the AMM.
|
||||
*/
|
||||
function deposit() public payable returns (uint256 tokensDeposited) {}
|
||||
function deposit() public payable returns (uint256 tokensDeposited) {
|
||||
require(msg.value > 0, "Must send value when depositing");
|
||||
uint256 ethReserve = address(this).balance - msg.value;
|
||||
uint256 tokenReserve = token.balanceOf(address(this));
|
||||
uint256 tokenDeposit;
|
||||
|
||||
tokenDeposit = (msg.value * tokenReserve / ethReserve) + 1;
|
||||
|
||||
require(token.balanceOf(msg.sender) >= tokenDeposit, "insufficient token balance");
|
||||
require(token.allowance(msg.sender, address(this)) >= tokenDeposit, "insufficient allowance");
|
||||
|
||||
uint256 liquidityMinted = msg.value * totalLiquidity / ethReserve;
|
||||
liquidity[msg.sender] += liquidityMinted;
|
||||
totalLiquidity += liquidityMinted;
|
||||
|
||||
require(token.transferFrom(msg.sender, address(this), tokenDeposit));
|
||||
emit LiquidityProvided(msg.sender, liquidityMinted, msg.value, tokenDeposit);
|
||||
return tokenDeposit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice allows withdrawal of $BAL and $ETH from liquidity pool
|
||||
* NOTE: with this current code, the msg caller could end up getting very little back if the liquidity is super low in the pool. I guess they could see that with the UI.
|
||||
*/
|
||||
function withdraw(uint256 amount) public returns (uint256 ethAmount, uint256 tokenAmount) {}
|
||||
function withdraw(uint256 amount) public returns (uint256 ethAmount, uint256 tokenAmount) {
|
||||
require(liquidity[msg.sender] >= amount, "withdraw: sender does not have enough liquidity to withdraw.");
|
||||
uint256 ethReserve = address(this).balance;
|
||||
uint256 tokenReserve = token.balanceOf(address(this));
|
||||
uint256 ethWithdrawn;
|
||||
|
||||
ethWithdrawn = amount * ethReserve / totalLiquidity;
|
||||
|
||||
uint256 tokenAmount = amount * tokenReserve / totalLiquidity;
|
||||
liquidity[msg.sender] -= amount;
|
||||
totalLiquidity -= amount;
|
||||
(bool sent, ) = payable(msg.sender).call{value: ethWithdrawn}("");
|
||||
require(sent, "withdraw(): revert in transferring eth to you!");
|
||||
require(token.transfer(msg.sender, tokenAmount));
|
||||
emit LiquidityRemoved(msg.sender, amount, tokenAmount, ethWithdrawn);
|
||||
return (ethWithdrawn, tokenAmount);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user