Operational Details

Obtaining a license

To use the Totle API clients first must sign a licensing agreement with Totle (instructions here)

Submitting a Request

The curl command below shows how a client can make requests to the Totle API providing input parameters, which are listed under Inputs for each of the API endpoints in the API Documentation section below.

curl 'https://services.totlesystem.com' -X POST \

-H 'Accept: application/json, text/plain, */*' \

-H 'Content-Type: application/json;charset=UTF-8' \

--data-binary ‘{<input parameters="">}’

Setting Allowances

Clients of Totle’s API retain custody of their funds at all times (i.e. there are no trader deposits). Totle’s smart contracts move tokens directly into and out of trader wallets. In order to execute non-custodial swaps the settlement smart contracts must have permission to move ERC20 tokens directly from counterparty wallets. The ERC20 standard specifies an approve/transferFrom mechanism that DEX contracts use to accomplish this.

Trades that involve selling (i.e. spending) ERC20 tokens from the trader’s wallet will only execute successfully if the trader has first executed an approve transaction allowing the DEX settlement contract to transfer those tokens. The amount of coins that a trader allows the smart contract to spend is called an allowance. A trader making a single trade may set a fixed allowance, or, when making several trades spending the same token with the same contract, may prefer to set an infinite allowance so they don’t have to continually replenish the allowance with additional approve transactions.

Every ERC20 token that a DEX contract will transfer from the trader’s wallet requires a prior approve transaction. When trading directly with multiple DEXs an approve transaction needs to be executed for each token and each DEX. Totle simplifies this by only requiring users to approve an allowance for the Totle TokenTransferProxy Contract.

Clients who wish to sell ERC20 tokens should execute the approve method of each ERC20 token contract passing Totle’s TokenTransferProxy Contract address. If the client sets the allowance for the exact amount of tokens to sell, then it must set the allowance again each time it wishes to sell more tokens. Alternatively, clients may set an unlimited allowance once and then trade the token an unlimited amount of times without having to go through this step again.

Below is an example of how to set an unlimited allowance for the Totle TokenTransferProxy.

const contract = new web3.eth.Contract(ERC20_ABI, TOKEN_ADDRESS)

const newAllowance = String((2 ** 256) - 1)

const data = contract.methods.approve(

TOKEN_TRANSFER_PROXY_ADDRESS, newAllowance).encodeABI()

const txPromise = wallet.sendTransaction({

to: TOKEN_ADDRESS,

value: '0',

gas,

gasPrice,

data

})

Displaying a Summary

The payload returned by the rebalance API endpoint is optimized for smart contracts and not human readable. If the trader is a human being signing a transaction, it’s often helpful to display a summary of what they’re signing. For this reason, the rebalance API returns a summary of the trades that will be executed as part of the transaction. The summary JSON looks something like this:

"summary": {

"sells": [

{

"token": "0xe41d2489571d322189246dafa5ebde1f4699f498",

"exchange": "Kyber",

"price": "0.003428358245615946",

"amount": "1000000000000000000",

"fee": "0"

}

],

"buys": [

{

"token": "0x1985365e9f78359a9b6ad760e32412f4a445e862",

"exchange": "AirSwap",

"price": "0.073153949999999993",

"amount": "1000000000000000000",

"fee": "0"

}

]

}

The “sells” array enumerates the ERC20 tokens that will be transferred from the client’s wallet and the buys array enumerates the ERC20 tokens that will be transferred to the client’s wallet. Each entry includes the token identifier (see the tokens API endpoint below for how to obtain a human readable map of these values), exchange that will perform the transfer, the price and amount.

Signing and Submitting a Transaction

After receiving a response to the rebalance API call, the payload needs to be signed and submitted to the Ethereum network for mining. Both of these things can be done using web3 library functions signTransaction and sendTransaction. For example, using the gas, ethValue, and payload fields returned from rebalance, one can construct a transaction to sign and send it as follows:

var Tx = require('ethereumjs-tx');

var privateKey = WALLET_PRIVATE_KEY;

var rawTx = {

nonce: nextNonce,

gasPrice: gas.price,

gas: gas.limit,

to: TOTLE_PRIMARY_CONTRACT_ADDRESS,

value: ethValue,

data: payload.data

}

var tx = new Tx(rawTx);

tx.sign(privateKey);

var serializedTx = tx.serialize();

web3.eth.sendSignedTransaction('0x' + serializedTx.toString('hex'))

.on('receipt', console.log);

Token Price and Quantity

There are two components to any trade: price and quantity. Through Totle’s API, you can control the maximum price you're willing to pay, as well as the minimum quantity you're willing to receive.

It is possible for trade prices to change during trade execution. This is because Totle integrates with different types of DEXs, each using different pricing mechanisms. Therefore, we’ve made it easy for you to control the maximum amount of price slippage you are willing to handle with each request you make.

After we’ve satisfied your price slippage tolerance, we try to find a set of orders that satisfy the quantity of tokens you’re looking to trade. In the event there are not enough tokens for your request’s price tolerance, it might make sense to allow some quantity slippage in the API request.
The Totle API will check the following two conditions after you sign and submit your trade:

Actual Price ≤ Response Price + Allowable Price Change (%) * Response Price

Actual Token Quantity ≥ Minimum Token Fill Quantity(%) * Requested Token Quantity


If both conditions are true, the transaction continues. Otherwise, the transaction reverts and no tokens move.

Token Amounts

When providing token amounts to the API for the /swap and /rebalance endpoints, the amount you provide should be in the token's base unit of decimals. The conversation factor to get this high-precision decimal number is 1*10^(-x) where x is the token decimals. For example, if you're working with 1 MKR, its representation using the token's base unit of decimals is 0.000000000000000001 MKR.

Gas

When signing and submitting transactions for execution most wallets provide the option of setting the gas price for the transaction. In general, setting a higher gas price results in the transaction getting mined sooner because miners try to maximize their fees when constructing blocks. However, because setting a higher gas price is a common way to front-run DEX transactions, some DEXs try to combat this by setting limits on gas price. So setting a gas price above those limits will result in the transaction failing.To assist clients in determining the right gas price certain Totle API calls include a “gas” field in the response, which looks like this:

"gas": {

"price": "10000000000",

"strict": false,

"limit": "1360000"

}

The gas.price field is the suggested gas price for the payload provided. A higher gas price can be set, however, if the gas.strict flag is set to true, we strongly recommend using gas.price to prevent the transaction from failing. Our API optimizes the gas values for optimal execution.

The gas.limit field is the suggested minimum gas limit for the payload provided. It is based on the number and complexity of orders that will be settled and the Suggester’s knowledge of the average gas consumed by trades on the various DEXs. We strongly recommend setting a gas limit at or above the value for gas.limit.

Fees

Fees are implemented as affiliate contracts.

An affiliate contract is created by calling the function registerAffiliate(address affiliateBeneficiary, uint256 affiliatePercentage) on the AffiliateRegistry (currently on mainnet at `0xd6C11526D4f71121B9F724676F86e19873245684`) where:

  • affiliateBeneficiary is the address you want to receive the fees at
  • affiliatePercentage is the percentage fee you want to take. affiliatePercentage is out of 1 ETH (i.e., 10% is 0.1 ETH and 0.1% is 0.001 ETH)


When registerAffiliate is called, the registry will emit a AffiliateRegistered(address affiliateContract) event (where affiliateContract is the address of the contract you've created).

When you want to accrue fees, you will include the affiliateContract in your API request to the /swap or /rebalance endpoints. Here's an example:

{

"affiliateContract": "0x...addressOfAffiliateContract",

"sells": [

{

"token": "0xe41d2489571d322189246dafa5ebde1f4699f498",

"amount": "1000000000000000000",

}

],

"breakdown":true,

"address": "0x..."

}

The encoded payload that is returned will include your affiliate contract. When the transaction is executed, the fee (in ETH) will be sent to your affiliate contract. Note that the ethValue in the returned payload includes any fees defined by the affiliate contract for all buy orders. For sell orders, the fee will be deducted from the ETH returned to the user's wallet.

To collect your fees, someone must call the payout() function on your affiliate contract. Anybody can call this, and it will payout the appropriate fees to the affiliateBeneficiary and to Totle.

The TotlePrimary contract has a default affiliate contract with an affiliatePercentage of 0.5% for when one isn't included in the rebalance payload. The fee calculations would then be as follows:

     Trade Value = ETH spent on buys + ETH received from sells
     Fee = 0.5% * Trade Value

If you include your affiliate contract in your request, the fees will be the summation of what you charge, plus the 0.5% assessed by Totle.

Developer Console

You can create affiliate/Partner Fee Contracts in just a few steps using the Totle Developer Console. This allows you to receive commission whenever a signed payload is submitted to the TotlePrimary contract from your Partner Fee contract.

There are no limits on how many affiliate contracts you can deploy.

Create and Deploy Contracts

To create a new contract and deploy it, you'll need to provide:

  • A name for the contract
  • The fee (as a percentage) that you would like to charge per transactions
  • The wallet address to which you would like fees to be paid to

Once you have deployed your affiliate contract, you can include its contract address in your API calls using the `affiliateContract` in the payload body to route fees for successful transactions to the contract.


You can claim the fees you earned at any time using the Developer Console.

Looking for something else? Send us your feedback.

Heading