搭建去中心化交易所——分享一个简单的DEX项目代码及文档

分享一个简单的DEX项目代码及文档

Dex.top项目源码及文档分享

// DEx.top - Instant Trading on Chain
//
// Author: DEx.top Team

pragma solidity 0.4.21;
pragma experimental "v0.5.0";

interface Token {
  function transfer(address to, uint256 value) external returns (bool success);
  function transferFrom(address from, address to, uint256 value) external returns (bool success);
}

contract Dex2 {
  //------------------------------ Struct Definitions: ---------------------------------------------

  struct TokenInfo {
    string  symbol;       // e.g., "ETH", "ADX"
    address tokenAddr;    // ERC20 token address
    uint64  scaleFactor;  // <original token amount> = <scaleFactor> x <DEx amountE8> / 1e8
    uint    minDeposit;   // mininum deposit (original token amount) allowed for this token
  }

  struct TraderInfo {
    address withdrawAddr;
    uint8   feeRebatePercent;  // range: [0, 100]
  }

  struct TokenAccount {
    uint64 balanceE8;          // available amount for trading
    uint64 pendingWithdrawE8;  // the amount to be transferred out from this contract to the trader
  }

  struct Order {
    uint32 pairId;  // <cashId>(16) <stockId>(16)
    uint8  action;  // 0 means BUY; 1 means SELL
    uint8  ioc;     // 0 means a regular order; 1 means an immediate-or-cancel (IOC) order
    uint64 priceE8;
    uint64 amountE8;
    uint64 expireTimeSec;
  }

  struct Deposit {
    address traderAddr;
    uint16  tokenCode;
    uint64  pendingAmountE8;   // amount to be confirmed for trading purpose
  }

  struct DealInfo {
    uint16 stockCode;          // stock token code
    uint16 cashCode;           // cash token code
    uint64 stockDealAmountE8;
    uint64 cashDealAmountE8;
  }

  struct ExeStatus {
    uint64 logicTimeSec;       // logic timestamp for checking order expiration
    uint64 lastOperationIndex; // index of the last executed operation
  }

  //----------------- Constants: -------------------------------------------------------------------

  uint constant MAX_UINT256 = 2**256 - 1;
  uint16 constant MAX_FEE_RATE_E4 = 60;  // upper limit of fee rate is 0.6% (60 / 1e4)

  // <original ETH amount in Wei> = <DEx amountE8> * <ETH_SCALE_FACTOR> / 1e8
  uint64 constant ETH_SCALE_FACTOR = 10**18;

  uint8 constant ACTIVE = 0;
  uint8 constant CLOSED = 2;

  bytes32 constant HASHTYPES =
      keccak256('string title', 'address market_address', 'uint64 nonce', 'uint64 expire_time_sec',
                'uint64 amount_e8', 'uint64 price_e8', 'uint8 immediate_or_cancel', 'uint8 action',
                'uint16 cash_token_code', 'uint16 stock_token_code');

  //----------------- States that cannot be changed once set: --------------------------------------

  address public admin;                         // admin address, and it cannot be changed
  mapping (uint16 => TokenInfo) public tokens;  // mapping of token code to token information

  //----------------- Other states: ----------------------------------------------------------------

  uint8 public marketStatus;        // market status: 0 - Active; 1 - Suspended; 2 - Closed

  uint16 public makerFeeRateE4;     // maker fee rate (* 10**4)
  uint16 public takerFeeRateE4;     // taker fee rate (* 10**4)
  uint16 public withdrawFeeRateE4;  // withdraw fee rate (* 10**4)

  uint64 public lastDepositIndex;   // index of the last deposit operation

  ExeStatus public exeStatus;       // status of operation execution

  mapping (address => TraderInfo) public traders;     // mapping of trade address to trader information
  mapping (uint176 => TokenAccount) public accounts;  // mapping of trader token key to its account information
  mapping (uint224 => Order) public orders;           // mapping of order key to order information
  mapping (uint64  => Deposit) public deposits;       // mapping of deposit index to deposit information

  //------------------------------ Dex2 Events: ----------------------------------------------------

  event DeployMarketEvent();
  event ChangeMarketStatusEvent(uint8 status);
  event SetTokenInfoEvent(uint16 tokenCode, string symbol, address tokenAddr, uint64 scaleFactor, uint minDeposit);
  event SetWithdrawAddrEvent(address trader, address withdrawAddr);

  event DepositEvent(address trader, uint16 tokenCode, string symbol, uint64 amountE8, uint64 depositIndex);
  event WithdrawEvent(address trader, uint16 tokenCode, string symbol, uint64 amountE8, uint64 lastOpIndex);
  event TransferFeeEvent(uint16 tokenCode, uint64 amountE8, address toAddr);

  // `balanceE8` is the total balance after this deposit confirmation
  event ConfirmDepositEvent(address trader, uint16 tokenCode, uint64 balanceE8);
  // `amountE8` is the post-fee initiated withdraw amount
  // `pendingWithdrawE8` is the total pending withdraw amount after this withdraw initiation
  event InitiateWithdrawEvent(address trader, uint16 tokenCode, uint64 amountE8, uint64 pendingWithdrawE8);
  event MatchOrdersEvent(address trader1, uint64 nonce1, address trader2, uint64 nonce2);
  event HardCancelOrderEvent(address trader, uint64 nonce);
  event SetFeeRatesEvent(uint16 makerFeeRateE4, uint16 takerFeeRateE4, uint16 withdrawFeeRateE4);
  event SetFeeRebatePercentEvent(address trader, uint8 feeRebatePercent);

  //------------------------------ Contract Initialization: ----------------------------------------

  function Dex2(address admin_) public {
    admin = admin_;
    setTokenInfo(0 /*tokenCode*/, "ETH", 0 /*tokenAddr*/, ETH_SCALE_FACTOR, 0 /*minDeposit*/);
    emit DeployMarketEvent();
  }

  //------------------------------ External Functions: ---------------------------------------------

  function() external {
    revert();
  }

  // Change the market status of DEX.
  function changeMarketStatus(uint8 status_) external {
    if (msg.sender != admin) revert();
    if (marketStatus == CLOSED) revert();  // closed is forever

    marketStatus = status_;
    emit ChangeMarketStatusEvent(status_);
  }

  // Each trader can specify a withdraw address (but cannot change it later). Once a trader's
  // withdraw address is set, following withdrawals of this trader will go to the withdraw address
  // instead of the trader's address.
  function setWithdrawAddr(address withdrawAddr) external {
    if (withdrawAddr == 0) revert();
    if (traders[msg.sender].withdrawAddr != 0) revert();  // cannot change withdrawAddr once set
    traders[msg.sender].withdrawAddr = withdrawAddr;
    emit SetWithdrawAddrEvent(msg.sender, withdrawAddr);
  }

  // Deposit ETH from msg.sender for the given trader.
  function depositEth(address traderAddr) external payable {
    if (marketStatus != ACTIVE) revert();
    if (traderAddr == 0) revert();
    if (msg.value < tokens[0].minDeposit) revert();
    if (msg.data.length != 4 + 32) revert();  // length condition of param count

    uint64 pendingAmountE8 = uint64(msg.value / (ETH_SCALE_FACTOR / 10**8));  // msg.value is in Wei
    if (pendingAmountE8 == 0) revert();

    uint64 depositIndex = ++lastDepositIndex;
    setDeposits(depositIndex, traderAddr, 0, pendingAmountE8);
    emit DepositEvent(traderAddr, 0, "ETH", pendingAmountE8, depositIndex);
  }

  // Deposit token (other than ETH) from msg.sender for a specified trader.
  //
  // After the deposit has been confirmed enough times on the block
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值