Im token logo imToken API Documentation DApp-SDK Tokenlon-Onboarding Tokenlon-MMSK Tokenlon-MMProxy Tokenlon-JSSDK Tokenlon-Open-API
  • 1. Summary
  • 2. Contracts
  • 3.Market Maker Access
  • English

    1. Summary

    Tokenlon is imToken's decentralized trading platform, designed to provide imToken users with "faster transaction", "better price", and reliable trading service with "wider selection". The platform applies traditional OTC RFQ/RFS model as its core trading protocol. Users can easily exchange Tokens at Tokenlon without having to transfer the Tokens out of the wallet. For how-to, please click imToken APP and navigate to "Market" at the bottom accessing "Tokenlon" module. You can select the tokens and then start trading.

    1. Quotation Mode

    Tokenlon applies RFQ(Request-For-Quote)/RFS(Request-For-Stream) mode. The process is similar to a traditional forex OTC desk. Users go to Tokenlon looking for best bid/offer by RFQ. The user requests are sent over to all market makers and the return quotes are aggregated for the best rates. Once the rates are confirmed by the user, the transactions will be sent over to market makers for execution.


    The above figure shows the RFQ process. Upon user request, the Tokenlon Server will request different market makers to return the best quotes to the user.

    2. Market Maker Quotation

    After the user session is established, the Tokenlon Server starts RFQ per Token pair for every 4 seconds, and the prices of all the market makers will be aggregated, then returned to the users.

    The market maker side handling is as follows:


    The above MMProxy and MMSK are provided by imToken, and need to be deployed and managed by market makers themselves. The MMProxy will be deployed on Ethereum in advance by imToken.

    3. Off-chain Quotation, On-chain Settlement

    Tokenlon uses off-chain quotation and on-chain settlement to improve the matching efficiency, as the significant amount of frequent user requests are discarded according to the RFQ/RFS.

    Advantages of off-chain quotation:

    • High efficiency: The existing on-chain quotation models are limited by the block processing time (except algorithmic quotation, which for other reasons fails to meet our demand).

    • Precision: The price determined by off-chain is guaranteed to settle on-chain, as "you get what you click" for the users. A design of quoting on-chain, however will be problematic, relies on speed of blocks, front-running, and uncertain (even failed) final transaction prices.

    Users can choose the most recent quote among stream of real-time off-chain offers. The order is signed by the user and sent to the Ethereum blockchain. In the end, the smart contract on Ethereum handles the trade, exchanging the assets of users' with those of market makers' to complete the trade.


    2. Contracts

    1. Overall Architecture

    The Tokenlon protocol is designed and based on 0x protocol which is used to complete atomic token exchange. It supports ERC20, ETH/Token, Token/ETH and Token/Token trades.

    The protocol consists of TokenlonExchange, MarketMakerProxy and UserProxy.


    As shown in the above figure, the entire trade will be sent to TE contract. After the contract is checked, the transaction will be sent to 0x Exchange (0x protocol). As can be seen in the figure, the 0x Exchange is followed by the 0xERC20Proxy contract, which is used to execute the token exchange. After 0x Exchange confirms that the transaction is correct (usually the signature verification and balance check of both parties, etc.), the 0xERC20Proxy will exchange the token from UserProxy and MMProxy according to the amount specified in the order.

    2. MMProxy

    Each market maker has an independent MMProxy contract to manage token deposit. This means that when a trade occurs, the token required by the user will be deducted from the MMProxy, and accordingly, the token deducted from the user will be stored in the MMProxy. Therefore, market makers should always keep sufficient token deposit in MMProxy. If the balance of some token is insufficient during the trade, the trade will eventually fail, and no funds in the user or contract will be deducted at all.

    How is token deduction made in the transaction?

    As we learned in the previous section, the tokens are ultimately exchanged by the 0xERC20Proxy contract. How does this exchange take place?

    The order is generated by MMSK according to the quotation engine of the market maker. The order will be signed by a wallet address called SIGNER, which cryptographically guarantees the legitimacy of the order. This order will contain basic information of tokenA-tokenB, such as tokenA's amount = 1 and tokenB's amount = 100, then the price at this time is actually 100/1 = 100.00 (i.e. one tokenA can be exchanged for 100 tokenBs).

    The user confirmed that the order was completed at a price of 100.0. The USER will sign the order with his user wallet and send the transaction to the TE contract. As shown in the previous section, this transaction will be transferred to 0x Exchange contract.


    0x Exchange verifies the signature of the order after receiving the transaction. Exchange calls isValidSignatrue methods of UserProxy and MMProxy respectively. If these two methods return true, the signature verification is successful and the token clearing phase of 0xERC20Proxy is entered.

    Next, the 0xERC20Proxy will transfer one token from UserProxy to MMProxy and 100 tokens from MMProxy to UserProxy according to the information in the order.

    How to rebalance funds?

    If users continue to buy TokenA with TokenB, there will be more and more token A in MMProxy and fewer TokenB, which requires to have two token accounts rebalanced.

    The withdraw interface is provided in the MMProxy contract, which market makers can call to withdraw a tokenA from the MMProxy. For the tokenB with insufficient balance, the market maker can use any wallet to transfer tokenB to the MMProxy contract address.

    For example, KNC token and cash withdrawal and collection address exist in the Kovan environment:

    Use Withdraw in DApp to carry out cash withdrawal. The corresponding parameters in the DApp are shown in the following figure:

    DApp 参数

    Among them, the first item is the token address to be withdrawn, the second item is the collection address to be withdrawn to, and the third item is the withdrawal amount.

    Please note: Withdrawal limit is of the uint type. If 1 WETH is withdrawn, it is 1 * pow(10,18), i.e. 10000000000000000, and 18 in pow is decimals of WETH.

    How to ensure MMProxy's security?

    In the contract, we set up three kinds of permissions, namely owner, operator and signer.

    Reasonable use of three permissions can ensure the security of MMProxy. Reference

    • MMProxy contract will be uniformly deployed by imToken and distributed to market makers. And handed over the highest authority (owner) of MMProxy to the market maker.

    3.Market Maker Access

    The market maker access is divided into two parts, one is to configure the contract and transfer tokens to the contract; The second is to deploy MMSK and provide quotation to MMSK.

    1. Configure MMProxy contract

    MMProxy is the capital pool of market makers. All token used by market makers for market making need to be recharged into the contract.

    Tokenlon-MMProxy contract document

    How to configure the MMProxy contract

    • Ethereum blockchain has the Ethereum mainnet and Kovan testnet. ETH token on each network is independent from each other. All ETH tokens on Kovan have no value and are only used for testing.
    1. Use imToken to create a wallet, then copy the Ethereum address and provide it to imToken. Wallet tutorial.

    2. If it is a test environment, imToken needs to be switched to developer mode (kovan environment) for configuration. For Prod/Staging environment skip this step.

      1. In the imToken 2.0 app, go to "My Profile" - "About Us", click the imToken logo 10 times, to open developer mode
      2. Go to "My Profile" - "Settings" - "Node Settings" - "Ethereum", and select Development. Click save to switch to Kovan testnet. You can also use this setting when switching from Kovan to Prod/Staging.
    3. Use the imToken DApp Browswer to open the permissions and settings DApp:{contract address provided by imToken}, DApp browser usage tutorial.

    4. Set the operator in the DApp, and the operator has all the operation rights of the contract.

      1. In a test environment, you can set owner\operator\signer to the same wallet address. In production environment, we suggest to use different wallets for the permissions. (Refer to 合约安全操作). Note: Only the wallet with the corresponding permission can enter the DApp to perform the corresponding operation of the contract. Otherwise, the button is not available. Even if the contract operation transaction is sent, the transaction will fail.
    5. Go back to the imToken wallet and switch the wallet to the operator wallet you just set. If the operator is the current wallet, you don't need to switch. Re-enter the DApp after switching the wallet.

    6. Use operator wallet to set signer. signer should be consistent with what you set as marketMakerSigner in MMSK.

    7. As mentioned in Section 2 of Chapter 2, the supported tokens need to be authorized with 0xERC20Proxy. Therefore, a token authorization operation is required. Take the kovan environment as an example (the following are the addresses of the kovan environment, Production/Staging requires the mainnet address):

      1. WETH:0xd0a1e359811322d97991e03f863a0c30c2cf029c // Note: The contract does not support ETH deposits, but WETH
      2. KNC:0x25570c5f2058efc52ff34e47631f41b5f6595d42
      3. Spender:0xf1ec01d6236d3cd881a0bf0130ea25fe4234003e // Note: This is the Kovan address of 0xERC20Proxy contract
      4. Use SetAllowance in the DApp for authorization, and the corresponding parameters in DApp are shown in the following configuration:

        DApp 参数

      5. Among them, the first item is the token address, which can be filled in batch and separated by,. The spender address in item 2 is the 0xERC20Proxy address. After filling the fields, click the SetAllwance button. Note: SetAllowance is only required once per token, and repeated setting may result in transaction failure.

    8. Deposit tokens to MMProxy. Use any wallet to transfer the specified ERC20 token to the MMProxy address. Note: Non-ERC20 tokens cannot be retrieved after being transferred into MMProxy.

    2. Deploy MMSK

    The function of MMSK is to automatically sign the quotation into an order and feed back the price information to Tokenlon Server.

    For installation steps of MMSK, see: tokenlon-mmsk

    Note: The contract configuration should be completed before deploying MMSK. Other MMSK related configuration information needs to be synchronized with the imToken team.

    Basic Requirements for MMSK Service

    1. MMSK Interface Minimum Response Time (i.e. Market Maker Quotation Engine Maximum Delay): 1s
      1. Relying on server deployment areas, it is recommended to deploy in Hong Kong, Japan, Singapore, Taiwan and other APAC locations.
      2. Depending on the implementation of market makers indicativePrice and price interface implementation (i.e. the processing efficiency of the quotation engine, considering the network delay, it is recommended that the calculation period is less than 400 milliseconds)
      3. Depending on the market maker interface: zerorpc is recommended; Even if it is provided by http, the internal network request method is needed to reduce the time consumption of external network requests.
    2. In indicativePriceprice interfaces
      1. Price provision via base and quote, for example, ETH/USDT exists in the pairs interface. Market makers need to support price return of the following four transaction parameters (where the amount is always the number of base tokens)
        1. base: 'ETH', quote: 'USDT', side: 'BUY', amount: xxx
        2. base: 'ETH', quote: 'USDT', side: 'SELL', amount: xxx
        3. base: 'USDT', quote: 'ETH', side: 'BUY', amount: xxx
        4. base: 'USDT', quote: 'ETH', side: 'SELL', amount: xxx
      2. Support minAmount, maxAmount returns, and quantitive directions
        1. minAmount, maxAmount always represents the minimum and maximum transactable quantity of base token base
        2. minAmount is always less than maxAmount, and further minAmount and maxAmount have a certain quantity input interval in between
        3. result: false, exchangeable: false cases, always return minAmount, maxAmount
        4. When the returned amount is smaller than the market maker's minAmount or greater than the market maker's maxAmount, the market maker needs to return result: false, exchangeable: false, message: 'xxx', in response to failure to quote

    3. FAQ

    MMSK Relevant Information

    1. Is the wallet address for MMSK deployment and the private key configuration both the signer wallet?

    Yes, the wallet address set via setSigner and MMProxy proxy contract is the same and belongs to the hot wallet. According to the contract security proposal, a cold wallet is also required to be configured for the MMProxy proxy contract setting operation (operator) role.

    2. Which protocol should I use for the MMSK API

    The interface supports both http and zerorpc. We recommend zerorpc for faster performance.

    3. In case 2 market makers reported the same quotation. Who is the preferred one?

    Based on Price/Time priority, who comes first will be served first.

    4. If the user submits an order for 1000 ETH, but all the markets do not have a quote for 1000 ETH, how can I handle this situation?

    We require market makers to give the maximum and minimum acceptable quantities. If the maximum is exceeded, we will directly prompt that orders cannot be placed.

    5. Do I need to deploy multiple MMSK based on for trading pairs?

    No, only one MMSK needs to be deployed. Market makers provide all trading pairs through one pairs interface.

    6. When will maximum and minimum quantities be returned?

    The maximum and minimum quantity must be returned to minAmount and maxAmount under any circumstances (no matter whether price is returned normally, exchangeable is true or false), and minAmount must have a certain range with maxAmount. These two quantities are the maximum and minimum quantities that the market maker can support for this trade. On the one hand, they are used for the user to feed back in real time on the imToken operation interface and guide the user to input the quantity that meets the conditions. On the other hand, they are also a protection for the market maker's single transaction volume and position.

    7. base and quote in the price and indicativePrice interfaces, for e.g. KNC/ETH, are different for buying and selling directions. Does base and quote change for directions?

    Yes, the quote changes for the buying and selling directions, because Tokenlon doesn't have fixed trading pairs. Instead every token trade has a corresponding direction. The MMSK doesn't convert between directions internally to prevent errors in the quotations of market makers.

    Considering SNT and ETH, let's assume that the fair value of the exchange rate we calculated is 1 ETH = 7 SNT.

    Base = ETH, Quote = SNT, Buy price => 7.01

    Base = ETH, Quote = SNT, Sell price => 6.99

    Base = SNT, Quote = ETH, Buy price => 0.1429

    Base = SNT, Quote = ETH, Sell price => 0.1428

    8. If there's no pair besides ETH->SNT and SNT->ETH and users want to exchange ETH for SNT, and there's two different prices: 0.1429 and 6.99 (converted to 0.1431). How will this price be finally decided?

    For example, the left is ETH and the right is SNT. At this time, if the user inputs the quantity on the left, ETH will be used as BASE, SNT will be used as Quote, and side will be SELL, which means the user wants to sell ETH for SNT, and the amount is ETH(base) quantity. If the user inputs the quantity on the right, SNT will be used as BASE, ETH will be used as Quote, and side will be used as BUY, which means the user wants to buy SNT with ETH, and the amount is the number of SNT(base). Although there is no big difference in the interface display and user exchange results, it is mainly for the sake of consistency of our user input. For example, the user has entered the quantity on the right side. However, we always use one SNT as the base, so there is bound to be intermediate price conversion. On the one hand, such price conversion may have price errors for market makers. On the other hand, the user may have entered 1,000 SNT because he intended to have 1,000 SNTs in his hand. However, after such conversion, he may not be able to obtain the complete 1,000 SNT in the end, which may be 998.12727463

    Contract Relevant Information

    1. How do I get the correct contract address of each currency? For example, how do we know the address for adding the new coin OMG and setAllowance?

    You can confirm the contract address with the imToken team first.

    2. How do I withdraw money from the contract or transfer money to the address in the contract?

    Deposit trading Tokens to the MMProxy proxy contract, but do not deposit non-ERC20 which cannot be withdrawn. You cannot transfer ETH, you can only transfer WETH.

    3. In the test environment, ETH is converted to WETH and then transferred to the contract address. In the production environment, how does ETH of the exchange transfer

    The same operation also needs to be done to convert ETH to WETH, which needs to be first withdrawn from the exchange to imToken or another non-custodial wallet. Then use the wallet to transfer to the WETH contract 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2. The smart contract will automatically return WETH to your wallet address at 1:1 (withdraw ETH to the wallet. Send ETH to WETH Contract to receive the equivalent WETH and send it to the contract.

    4. If the contract security best practice requires the owner to be a cold wallet, how do I setOperator

    Check imToken cold wallet. It can be used to set the wallet MMProxy via the DAPP:

    5. Is there any deduction of handling fees during a trade?

    At present, a Tokenlon trade does not require a handling fee, but the final payment of the order requires miners' fee, which is paid by the person who made the final payment. The miners' fee a ETH-to-token trade is paid by the user. The miners' fee for a token-to-ETH trade is paid by imToken, to ensure a fast transaction. The market maker's signer wallet only signs and authorizes operations, and does not need to spend miners' fees.

    6. To rebalance, is there any place for operation apart from withdraw call in the MMProxy contract?

    Recharge: You can transfer money directly from the exchange or wallet to MMProxy agency contract, but be careful not to withdraw non-ERC20. Non-ERC20 cannot be withdrawn from the contract. ETH cannot be transferred, only WETH can be transferred.

    Withdrawal: You can use imToken to open the DApp for graphical operation. The DApp provided by imToken is actually an interface tool for the real contract interface MMProxy. Market makers who are familiar with Ethereum can also encode the ABI by themselves and send it to MMProxy contract to realize relevant functions such as cash withdrawal.