#### The partial fill feature
When an order is 100% filled, a single secret is used to finalize the transaction between two parties. However, when an order is only partially filled by different resolvers, revealing the secret to the public could let others claim the remainder of the order without completing their part.
To solve this, a Merkle tree of secrets is implemented for partial fills, which splits the order into equal parts and generates dedicated secrets for each portion of swap.
For example, if an order is divided into four parts, the first secret is used for the first 25%, the second for 50%, and so on. If a participant fills a part of the order, the next participant uses the corresponding secret based on the current progress to continue filling the order. This ensures that each participant can only fill their portion without exposing the rest of the order.
In the example image below, the 1st secret is used for the initial 0-20% fill, marking the first stage of the order. Secrets 2 and 3 are not used because the order skips directly from 20% to 80%, bypassing the ranges where these secrets would apply. The 4th secret is then used to fill the order from 20% to 80%, covering this larger portion. Finally, the 5th secret is used to complete the final 80-100% of the order, ensuring that the entire order is securely and progressively filled.
## API reference
For detailed information about each endpoint, refer to the Fusion+ API [OpenAPI specs](./relayer/v1.2/submit/method/post).
## After V 6.1
## API reference
For detailed information about each endpoint, refer to the classic swap API [OpenAPI specs](./methods/v6.1/1/quote/method/get).
## Quickstart
In order to quickly understand how to make an exchange using the protocol, we suggest you use the [Quickstart guide](./quick-start.md).
:::info
For workloads that require higher RPS, expanded quotas, or sustained performance, explore the available paid plans on the [**pricing page**](/pricing).
For organizations with significant trading volumes or advanced requirements, [**complete this application**](/get-enterprise) to explore tailored Enterprise options.
:::
{nft.description}
{nft.description}
1. Click on the returned farm contract address and navigate to the 'Write Contract' section of the returned contract page. This is your newly generated farm distribution address.
3. Call the `setDistributor` method using the address that will be managing and distributing rewards.
4. On the same contract, call `addRewardsToken` with the desired token address that will be distributed to your delegators.
5. Lastly, on the same contract, call `startFarming`, entering the `rewardsToken` address, amount, and period (both amount and period are uint256). Once called, your farm will have started, and rewards will begin to be distributed to your delegators.
--- ### How to Replenish Farming Token Balance (Optional) To replenish the token balance of your farm rewards, call `addRewardsToken` and `startFarming` to the farm contract as done in the initial setup. --- ### Example ABI Interaction :::info The example script below reads ABI definitions for both the [dst1inch](https://etherscan.io/token/0xAccfAc2339e16DC80c50d2fa81b5c2B049B4f947#code) and [multiFarmingPod](https://etherscan.io/address/0x1583C1dBe20625d0B752d472E845FbA96D096829#code) contracts. You will need to create two new files and add the ABI definitions which can be found at these URLS: - [`dst1inchABI.json`](https://api.etherscan.io/api?module=contract&action=getabi&address=0xAccfAc2339e16DC80c50d2fa81b5c2B049B4f947&apikey=YourApiKeyToken) - [`abi.json`](https://api.etherscan.io/api?module=contract&action=getabi&address=0x1583C1dBe20625d0B752d472E845FbA96D096829&apikey=YourApiKeyToken) Don't forget to replace 'YourApiKeyToken' with your actual Etherscan API key at the end of each linked URL above! ::: ```javascript require("dotenv").config(); //for accessing sensitive information such as private keys, API keys, etc. const { Web3 } = require("web3"); const web3 = new Web3(`Your_ethereum_RPC`); const fs = require("fs"); const dst1inchABI = JSON.parse(fs.readFileSync("dst1inchABI.json", "utf8")); const farmABI = JSON.parse(fs.readFileSync("abi.json", "utf8")); const erc20Abi = [ // ERC20 ABI fragment (for contract approval) { constant: false, inputs: [ { name: "spender", type: "address" }, { name: "value", type: "uint256" } ], name: "approve", outputs: [ { name: "", type: "bool" } ], payable: false, stateMutability: "nonpayable", type: "function" } ]; const dst1inch = "0xAccfAc2339e16DC80c50d2fa81b5c2B049B4f947"; const dst1inchContract = new web3.eth.Contract(dst1inchABI, dst1inch); const account = "YOUR_REGISTERED_ADDRESS"; const privateKey = "YOUR_PRIVATE_KEY"; async function distributeFarmingRewards(resolverAddress, newDistributor, rewardsToken, amount, period) { try { // Call defaultFarms with your resolver address const farmAddress = await dst1inchContract.methods.defaultFarms(resolverAddress).call(); console.log(`Farm address: ${farmAddress}`); const farmContract = new web3.eth.Contract(farmABI, farmAddress); const tokenContract = new web3.eth.Contract(erc20Abi, rewardsToken); // Call setDistributor on the returned farm address const setDistributorTx = { from: resolverAddress, to: farmAddress, data: farmContract.methods.setDistributor(newDistributor).encodeABI() }; const setDistributorSignedTx = await web3.eth.accounts.signTransaction(setDistributorTx, privateKey); await web3.eth.sendSignedTransaction(setDistributorSignedTx.rawTransaction); console.log("Distributor set successfully"); // Approve the farm contract to spend the tokens const approveTx = { from: newDistributor, to: rewardsToken, data: tokenContract.methods.approve(farmAddress, amount).encodeABI() }; const approveSignedTx = await web3.eth.accounts.signTransaction(approveTx, privateKey); await web3.eth.sendSignedTransaction(approveSignedTx.rawTransaction); console.log("Approval transaction confirmed"); // Call addRewardsToken with the address of distribution token const addRewardsTokenTx = { from: newDistributor, to: farmAddress, data: farmContract.methods.addRewardsToken(rewardsToken).encodeABI() }; const addRewardsTokenSignedTx = await web3.eth.accounts.signTransaction(addRewardsTokenTx, privateKey); await web3.eth.sendSignedTransaction(addRewardsTokenSignedTx.rawTransaction); console.log("Rewards token added successfully"); // Call startFarming(address rewardsToken, uint256 amount, uint256 period) const startFarmingTx = { from: newDistributor, to: farmAddress, data: farmContract.methods.startFarming(rewardsToken, amount, period).encodeABI() }; const startFarmingSignedTx = await web3.eth.accounts.signTransaction(startFarmingTx, privateKey); await web3.eth.sendSignedTransaction(startFarmingSignedTx.rawTransaction); console.log("Farming started successfully"); } catch (error) { console.error("Error distributing farming rewards:", error); } } const resolverAddress = account; const newDistributor = account; // you can use any address as the distributor const rewardsToken = "0xRewardsTokenAddress"; const amount = web3.utils.toWei("Amount", "Token Name"); // Amount of rewards tokens const period = 3600; // Period in seconds distributeFarmingRewards(resolverAddress, newDistributor, rewardsToken, amount, period) .then(() => console.log("Farming rewards distributed successfully")) .catch((error) => console.error("Error distributing farming rewards:", error)); ``` Have questions? Reach out to us in the live support chat!
- **Src is not set:** The 'src' (source token contract) field is missing.
- **Dst is not set:** The 'dst' (destination token contract) field is missing.
- **Insufficient liquidity:** The aggregator can't find a route for the swap due to low liquidity.
## Swap-specific Errors
- **Not enough src balance:** This means your source token balance is insufficient. It provides the required amount and your current balance.
- **Not enough Allowance:** You haven't granted the necessary token allowance to the 1inch router. It'll indicate the amount, current allowance, and the spender address, e.g., "Spender: 0x1111111254eeb25477b68fb85ed929f73a960582".
- **Insufficient liquidity:** As mentioned earlier, the aggregator couldn't route the swap.
:::info
For workloads that require higher RPS, expanded quotas, or sustained performance, explore the available paid plans on the [**pricing page**](/pricing).
For organizations with significant trading volumes or advanced requirements, [**complete this application**](/get-enterprise) to explore tailored Enterprise options.
:::
---
## What are the "parts" parameters?
The parts parameters is comprised of 3 things
- mainRouteParts
- virtualParts
- parts
Each of these has their own unique meaning. The main route parts denotes the initial split and can be seen on the UI. In this example it's the 70%/30% split
The parts parameter is how many individual blocks there can be. In the picture above we can see 4 blocks with the top being the first main route part with 2 parts to it and the bottom one being the second main route part with 2 parts in it.
The virtual parts is the splits _inside_ of a part. We can see in the first main route part above, in the first block there are 2 virtual parts splitting the USDC between hashflow and uniswap. In the second main route part we can see three virtual parts in the first block, a hashflow route with 2 different rates and one to uniswap.
## What is the "Complexity level?"
Complexity level is how many steps a swap can go through, below are the levels and what it means for the swap. Each level adds to the previous level.
- **Complexity level 0:** the source token can be wrapped or unwrapped and swapped through one liquidity pool per main route part.
- **Complexity level 1:** the source token can be wrapped or unwrapped and swapped through two liquidity pools. This means there can be up to one connector token in each main route part.
- **Complexity level 2 (Default):** the source token can be wrapped or unwrapped and swapped through three liquidity pools. This means there can be up to two connector tokens in each main route part.
- **Complexity level 3:** the source token can be wrapped or unwrapped and swapped through four liquidity pools. This means there can be up to three connector tokens in each main route part.
## How can I limit the liquidity sources in the query?
To limit the liquidity sources to a query, you can manually enter the pool-contacts that you to use using the "protocols" parameter. All other liquidity sources will be excluded by default.
### Still have questions?
Feel free to reach out to us in the live support chat!
:::tip Debugging with `X-Request-Id`
Every API response includes an `X-Request-Id` header that uniquely identifies your request. When contacting support, include this value for faster investigation. If you use the [1inch MCP Server](/portal/documentation/ai-integration/ecosystem), the `debug` tool can look up production logs by this request id.
:::