I am following scaffold eth 4th challenge to create DEX. It's smart contract has this deposit function logic:

function deposit() public payable returns (uint256 tokensDeposited) {
        uint256 ethReserve = address(this).balance.sub(msg.value); // why we are substracting here?
        uint256 tokenReserve = token.balanceOf(address(this));
        uint256 tokenDeposit;

        tokenDeposit = (msg.value.mul(tokenReserve) / ethReserve).add(1); // why we are adding 1 here?
        uint256 liquidityMinted = msg.value.mul(totalLiquidity) / ethReserve;
        liquidity[msg.sender] = liquidity[msg.sender].add(liquidityMinted);
        totalLiquidity = totalLiquidity.add(liquidityMinted);

        require(token.transferFrom(msg.sender, address(this), tokenDeposit));
        emit LiquidityProvided(msg.sender, liquidityMinted, msg.value, tokenDeposit);
        return tokenDeposit;

I have two doubts here:

  1. Why we are substracting the msg.value from address(this).balance? Why not add msg.value to address(this.balance) since we are increasing the amount of ETH in DEX.
  2. Why we are adding 1 there?
  3. How to determine how much to provide LP tokens to the depositor?

Thanks in advance

1 Answer 1


There's the subtraction because the variable ethReserve wants to indicate the value of ETH in the contract before the current deposit.

For example, if there were 10 ETH in the contract, and you call deposit with msg.value = 1 ETH, then immediately address(this).balance = 11 ETH. So to get the old reserve we must subtract address(this).balance - msg.value.


I believe they add 1 to make the division round up. Since tokenDeposit is the amount the user must pay, it's better to round it up to prevent exploits.

For example, let's say msg.value = 1, tokenReserve = 5 and ethReserve = 10. Then (msg.value.mul(tokenReserve) / ethReserve) = 0.5 so it rounds to 0. In this case the user would pay 0 tokens to add some liquidity, which may lead to exploits. So it's safer to round up. In most cases it doesn't really matter for "normal" amounts of tokens (like 18 decimals).


uint256 liquidityMinted = msg.value.mul(totalLiquidity) / ethReserve

The user is getting a liquidity proportional to the ETH amount he pays compared to the total.

If totalLiquidity = 20 and ethReserve = 10, a user paying 1 ETH would get 2 liquidity. This brings totalLiquidity = 22 and ethReserve = 11. Another user now pays 2 ETH: you can do the math and see that he gets 4 liquidity. This makes sense since they paid double compared to the first user. So this method is fair for everyone.

  • Thanks @0xSanson. My first two doubts are clear but I am having problem that what actually liquidityMinted variable represents? does it represents amount of LP tokens to provide or something else? Commented Nov 7, 2022 at 14:10
  • @RishabhRaghwendra I don't have the full code, but I believe it's similar to LP yes.
    – 0xSanson
    Commented Nov 7, 2022 at 20:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.