Santhosh Reddy
Santhosh Reddy

Follow

Santhosh Reddy

Follow
Sun Coin - ERC20 Token and a DEX

Sun Coin - ERC20 Token and a DEX

Santhosh Reddy's photo
Santhosh Reddy
·Mar 20, 2022·

5 min read

Play this article

Table of contents

  • Intro... 🙋‍♂️
  • Tech Stack... 🧑‍💻
  • ERC20 token... 🪙
  • DEX... 💵
  • Final Thoughts... 🙂

👋 Hello world! This is Santhosh Reddy, a 17 year old developer and a curious web3 learner. I keep building projects on blockchain like Dapps and smart contracts which reflects the real world use cases.

Intro... 🙋‍♂️

Back again with a new web3 project, SUNcoin - A ERC20 token deployed to Ropsten Testnet as well as a DEX to swap the tokens with ETH.

As said in the previous article on Nftify, I had never practically worked on ERC20 tokens till now. So I decided to create a token and also a DEX(Decentralized Exchange) to swap tokens using an Automated Market Maker (AMM) Algorithm.

Visit : SUNcoin & DEX

Code : Github Repo

Tech Stack... 🧑‍💻

  1. ReactJS (fronted UI)
  1. Web3JS (interact with smart contract)
  1. Solidity (create the erc721 smart contract)

ERC20 token... 🪙

I used OpenZeppelin framework to create a token. In the same file to the ERC20 token, I had written the code for Crowdsale(ICO) to allow users to mint tokens in the initial stage.

The admin(me) who deployed the token can start the crowdsale and then the users can mint tokens with an initial cost of 0.001ETH/SUN. I had minted 1000SUN tokens with 1ETH. At the end of the time period, the admin can end the crowdsale. Once ended, can never be started again.

After crowdsale has been completed, the total tokens minted by the users (1000SUN) are again minted to the DEX contract as reserveSupply and the total ETH holdings of the token contract are transferred to the DEX contract as marketCap.

So, initially :

totalSupply is 2000SUN,

circulationSupply is 1000SUN,

reserveSupply is 1000SUN,

marketCap is 1 ETH,

price is 0.001ETH/1SUN.

I think we should also discuss allowance in ERC20. In the process of swapping the tokens, the DEX contract should be able to transfer the tokens from your wallet while selling. But, to ensure the users' security the contract can't do it directly. Here you need to provide the allowance for a specific number of tokens for the DEX. The allowance should be managed by the user.

Here is the code of the token and crowdsale contract.


// SPDX-License-Identifier: MIT

pragma solidity ^ 0.8.0;


import "github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeMath.sol";

import "github.com/OpenZeppelin/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol";


contract SUNcoin is ERC20 {



  using SafeMath for uint;


  address public admin;


  constructor() ERC20('Sun','SUN') {

    admin = msg.sender;

  }


  function Approve(uint amount) external {

    approve(exchangePool, amount);

  }


  /* @CrowdSale */


  uint internal crowdsale;


  address internal exchangePool;


  event tokensMined(address by, uint amount);


  function startCrowdsale(address wallet) external {

    require(msg.sender == admin, "only admin");

    require(crowdsale == 0, "Crowdsale completed");

    crowdsale = 1;

    exchangePool = wallet;

  }


  function endCrowdsale() external {

    require(msg.sender == admin, "only admin");

    require(crowdsale == 1, "Crowdsale not yet started");

    crowdsale = 2;

    _mint(exchangePool, totalSupply());

    payable(exchangePool).transfer(address(this).balance);

  }  



  function crowdSale() external payable {

    require(crowdsale == 1, "crowdsale inactive");

    uint amount = msg.value.div(10**15);

    _mint(msg.sender, amount.mul(10**18));

    emit tokensMined(msg.sender, amount);

  }



}

DEX... 💵

A DEX - Decentralized Exchange is a place where you swap/exchange/buy-sell your tokens with others tokens or the main crypto currency of the network. Few most popular DEXs are Uniswap, PancakeSwap, etc... Sun coin app is also a DEX where only the SUN tokens can be swapped with ETH.

DEX's SUN holdings is referred as reserveSupply(x) and ETH balance as marketCap(y) and k = x*y is the constant of the Constant Product Market Maker(CPMM) algorithm which is a type of AMM.

k = 1000SUN * 1ETH = 1000

Value of k remain the same forever. If someone wants to buy SUN, they need to send ETH to DEX and should send SUN to DEX to recieve ETH.

For example, I own 1000SUN of the circulationSupply and want to buy some more SUN with 0.1 ETH. With k=x*y formula, now y=1+0.1=1.1 and y=k/y=909.1. So, now circulationSupply (1000SUN) should become 909.1 SUN.

So, I will receive the remaining 90.9 SUN. We can easily say that the price that I bought for is 0.0011ETH/1SUN. The price has increased right ? This is due to the increase in demand.

The same applies for selling the tokens but in a reverse way of x-y. Hope you understand how CPMM works.

Here is the DEX contract code with Buy and Sell functions that implements the CPMM algorithm.


//SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;


import "github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeMath.sol";

import "github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol";


contract DEX {



  using SafeMath for uint;


  IERC20 internal token;


  constructor() {

    token = IERC20(0x755529CAbA040EA7110143c7CD1d3Df599Da012a);

  }


  event Bought(uint256 amount);

  event Sold(uint256 amount);


  function buy() payable external {

    uint256 dexBalance = token.balanceOf(address(this));

    uint const = (address(this).balance.sub(msg.value)).mul(dexBalance);

    uint finalSupply = const.div(address(this).balance);

    uint amount = dexBalance.sub(finalSupply);

    require(msg.value > 0, "You need to send some ether");

    require(amount <= dexBalance, "Not enough tokens in the reserve");

    token.transfer(msg.sender, amount);

    emit Bought(amount);

  }    


  function sell(uint256 amount) external { 

    uint const = address(this).balance.mul(token.balanceOf(address(this)));

    uint finalSupply = token.balanceOf(address(this)).add(amount);

    uint amountTosend = address(this).balance.sub(const.div(finalSupply));

    require(amount > 0, "You need to sell at least some tokens");

    token.transferFrom(msg.sender, address(this), amount);

    payable(msg.sender).transfer(amountTosend); 

    emit Sold(amount);

  }


  fallback() external payable { }


}

Final Thoughts... 🙂

Finally completed all the projects that a blockchain developer must complete. I think I have covered almost all concepts of blockchain development like IPFS, Solidity Smart contracts, ERC721 & ERC20 tokens. I think it's time to research DAOs more deeply.

Hope my articles help you understand blockchain development. I found it helpful, please share it with your friends, give your reactions, comment down your suggestions and bugs in my code if found and follow me for more articles like this.

Uhhhhh.....

Taking a leave for now... 👋 Bye!

 
Share this