How does minimum viable dex work?

Please anyone make some of the code in the minimum viable dex a bit clearer to me. I know the formula is simple but I dont get it

    using SafeMath for uint256;
    IERC20 token;

    constructor(address token_addr) public {
        token = IERC20(token_addr);
    }

    uint256 public totalLiquidity;
    mapping(address => uint256) public liquidity;```

    
```function init(uint256 tokens) public payable returns (uint256) {
        require(totalLiquidity == 0, "DEX:init -already has liquidity");
        totalLiquidity = address(this).balance;
        liquidity[msg.sender] = totalLiquidity;
        require(token.transferFrom(msg.sender, address(this), tokens));
        return totalLiquidity;
    }```

    //how come totalLiquidity seems to track both the eth and token balance in the contract(i don't understand how that would work)
    //should we not have two variables to track the total amount of Eth and tokens separately?

    
```function price(
        uint256 input_amount,
        uint256 input_reserve,
        uint256 output_reserve
    ) public view returns (uint256) {
        uint256 input_amount_with_fee = input_amount.mul(997);
        uint256 numerator = input_amount_with_fee.mul(output_reserve);
        uint256 denominator =
            input_reserve.mul(1000).add(input_amount_with_fee);
        return numerator / denominator;
    }```

    //confused by how price is not actually money per token/eth but
    //  basically how much of the resulting output asset you will get
    //  if you put in a certain amount of the input asset.
    //what is the output_reserve?
    //the logic in the denominator


    
```function deposit() public payable returns (uint256) {
        uint256 eth_reserve = address(this).balance.sub(msg.value);
        uint256 token_reserve = token.balanceOf(address(this));
        uint256 token_amount =
            (msg.value.mul(token_reserve) / eth_reserve).add(1);
        uint256 liquidity_minted = msg.value.mul(totalLiquidity) / eth_reserve;
        liquidity[msg.sender] = liquidity[msg.sender].add(liquidity_minted);
        totalLiquidity = totalLiquidity.add(liquidity_minted);
        require(token.transferFrom(msg.sender, address(this), token_amount));
        return liquidity_minted;
    }```

    //why do we not just have the amount of tokens as an argument,
    //why are we calculating it inside the function
    //logic in liquidity minted??

    
```function withdraw(uint256 amount) public returns (uint256, uint256) {
        uint256 token_reserve = token.balanceOf(address(this));
        uint256 eth_amount = amount.mul(address(this).balance) / totalLiquidity;
        uint256 token_amount = amount.mul(token_reserve) / totalLiquidity;
        liquidity[msg.sender] = liquidity[msg.sender].sub(eth_amount);
        totalLiquidity = totalLiquidity.sub(eth_amount);
        (bool sent, bytes memory data) = msg.sender.call{value: eth_amount}("");
        require(sent, "Failed to transfer Ether");
        require(token.transfer(msg.sender, token_amount), "TRANSFER FAILED");
        return (eth_amount, token_amount);
    }
}```
    //why we have to calculate eth amount?? don't we keep a record using a mapping??
1 Like

Am reading from here https://medium.com/@austin_48503/️-minimum-viable-exchange-d84f30bd0c90

1 Like

Hi @Altaergo,

I haven’t been through this video/article before. I suggest watching it a couple of times and playing with the code. You could also try reaching out to Austin.

1 Like

Of course. I will try to go over the tutorial again, maybe looking at it with a fresh set of eyes will make it clearer :slight_smile:

1 Like