Skip to content

Repository files navigation

1inch Fusion Protocol

Build Status Coverage Status NPM Package License: MIT

Smart contracts for 1inch Fusion — the intent-based swap mode of the 1inch Network.

In Fusion, a user does not send a swap transaction. They sign an off-chain order for the 1inch Limit Order Protocol whose exchange rate improves over time as a Dutch auction. Professional market makers, called resolvers, compete to fill that order and pay the gas for it. The user gets a rate that no longer depends on their own gas budget or on the mempool, and the fill never becomes a public pending transaction that can be front-run.

This repository holds the on-chain half of that flow: the settlement extension that the Limit Order Protocol calls while filling a Fusion order, the registries that decide which resolvers may fill, and the access token that gates them.

How a Fusion order is settled

  1. The maker signs a limit order whose extension points at the settlement contract, so the contract acts as both the amount getter and the post-interaction handler for every fill.
  2. A resolver calls fillOrder on the Limit Order Protocol. SimpleSettlement computes the price for the current block through _getMakingAmount / _getTakingAmount, applying the auction rate bump encoded in the order's auctionDetails.
  3. In the post-interaction, the contract checks that the caller is allowed to fill right now. The whitelist is packed into the order itself as a start time plus per-resolver time deltas, which gives each whitelisted resolver an exclusivity window before the next one is allowed in. A taker outside the whitelist can only fill once the whole schedule has elapsed, and only while holding the access token.
  4. Fees are taken from the taking amount: an integrator fee, a protocol fee, and a configurable share of any surplus above the estimated taking amount quoted when the order was created.
  5. On Ethereum mainnet the Settlement contract additionally rejects a fill whose priority fee exceeds the cap set by 1inch DAO proposal, which stops resolvers from bidding away the user's surplus in gas.

The auction curve is a piecewise linear function: an initial rate bump that decays through a list of (rateBump, timeDelta) points down to zero at the end of the auction. The current base fee is folded into the calculation through gasBumpEstimate and gasPriceEstimate, so the part of the bump that merely compensates the resolver for gas disappears when gas is cheaper than it was at quote time.

Contracts

Contract Description
SimpleSettlement The settlement extension. Dutch auction pricing, whitelist and timing checks, integrator / protocol / surplus fees. Deployed on every supported network.
Settlement SimpleSettlement plus the mainnet priority fee cap.
WhitelistRegistry On-chain resolver whitelist. An address registers by holding at least a configured percentage of PowerPod total supply, and is evicted by clean() once it drops below that threshold. Resolvers also promote a worker address per chain to do the actual settling.
CrosschainWhitelistRegistry Per-chain worker promotions for resolvers, taking the resolver set from WhitelistRegistry instead of maintaining its own.
PowerPod Combines st1INCH farming and delegation with voting power, and is the token whose balances the whitelist threshold is measured against.
KycNFT The access token. An ERC-721 limited to one token per address, where minting and transfers are performed by the contract owner or by anyone presenting an EIP-712 signature from the owner.
ResolverMetadata Lets a registered resolver publish the URL of the metadata shown for it in the 1inch dApp.

Generated API documentation for each contract lives in docs/.

Repository layout

contracts/      Solidity sources
  helpers/      auxiliary contracts
  interfaces/   external interfaces
  mocks/        contracts used only by the tests
test/           Hardhat tests, including gas measurements
  helpers/      order-building helpers, also published in the npm package
deploy/         hardhat-deploy scripts, one per contract
scripts/        one-off operational scripts (KYC minting, ownership transfer)
config/         per-chain constants consumed by the deploy scripts
deployments/    hardhat-deploy artifacts per network, including addresses and ABIs
docs/           generated contract documentation

Getting started

The project uses Hardhat 2 with Node.js 20 and Yarn, and compiles with solc 0.8.23 via IR.

yarn                     # install dependencies
yarn hardhat compile     # compile the contracts
yarn test                # run the test suite in parallel
yarn test:ci             # run it sequentially, as CI does
yarn coverage            # solidity-coverage report
yarn lint                # eslint + solhint
yarn lint:fix            # autofix what can be autofixed
yarn docify              # regenerate docs/ from NatSpec

CI runs the linter, the test suite and the coverage report on every pull request.

To build on top of the contracts from another project, install the published package:

yarn add @1inch/limit-order-settlement

It ships the contract sources, the interfaces, and the order-building helpers in test/helpers.

Deployments

Addresses and ABIs are committed under deployments/ for every network below except the three most recent ones — Cronos, Monad and HyperEVM — whose artifacts have not landed in the repository yet.

Settlement

Deployment goes through a CREATE3 deployer, so the address depends on the salt rather than on the chain, and the same address is reused across a whole rollout. The original rollout shares one address across fourteen networks, the recent Cronos, Monad and HyperEVM deployments share another, and zkSync Era stands alone because it does not support CREATE3.

Ethereum mainnet runs Settlement, the variant with the priority fee cap; every other chain runs SimpleSettlement.

Network Chain ID Contract Address
Ethereum 1 Settlement 0x2Ad5004c60e16E54d5007C80CE329Adde5B51Ef5
Arbitrum One 42161 SimpleSettlement 0x2Ad5004c60e16E54d5007C80CE329Adde5B51Ef5
Aurora 1313161554 SimpleSettlement 0x2Ad5004c60e16E54d5007C80CE329Adde5B51Ef5
Avalanche 43114 SimpleSettlement 0x2Ad5004c60e16E54d5007C80CE329Adde5B51Ef5
Base 8453 SimpleSettlement 0x2Ad5004c60e16E54d5007C80CE329Adde5B51Ef5
BNB Chain 56 SimpleSettlement 0x2Ad5004c60e16E54d5007C80CE329Adde5B51Ef5
Cronos 25 SimpleSettlement 0x65497E56Cf49c51f1c1d54dc9005a7b38B98B30F
Fantom 250 SimpleSettlement 0x2Ad5004c60e16E54d5007C80CE329Adde5B51Ef5
Gnosis Chain 100 SimpleSettlement 0x2Ad5004c60e16E54d5007C80CE329Adde5B51Ef5
HyperEVM 999 SimpleSettlement 0x65497E56Cf49c51f1c1d54dc9005a7b38B98B30F
Kaia (Klaytn) 8217 SimpleSettlement 0x2Ad5004c60e16E54d5007C80CE329Adde5B51Ef5
Linea 59144 SimpleSettlement 0x2Ad5004c60e16E54d5007C80CE329Adde5B51Ef5
Monad 143 SimpleSettlement 0x65497E56Cf49c51f1c1d54dc9005a7b38B98B30F
Optimism 10 SimpleSettlement 0x2Ad5004c60e16E54d5007C80CE329Adde5B51Ef5
Polygon 137 SimpleSettlement 0x2Ad5004c60e16E54d5007C80CE329Adde5B51Ef5
Sonic 146 SimpleSettlement 0x2Ad5004c60e16E54d5007C80CE329Adde5B51Ef5
Unichain 130 SimpleSettlement 0x2Ad5004c60e16E54d5007C80CE329Adde5B51Ef5
zkSync Era 324 SimpleSettlement 0x8261425Bf01CAf25259dAbE36FD05F430b38AEe0

Other contracts

KycNFT, the access token passed to the settlement constructor, follows the same pattern: 0xAccE550000863572B867E661647CD7D97b72C507 on every network recorded in deployments/ (mainnet), except zkSync Era, where it is 0x46B64318C4f764F6Fe81dFd1F26282A52E0f1680.

The registries and the staking pod exist on Ethereum mainnet only:

Contract Address
WhitelistRegistry 0xcb8308fcB7BC2f84ed1bEa2C016991D34de5cc77
CrosschainWhitelistRegistry 0xBe89346fE1cE1367f3d80C8522209A86511B1201
PowerPod 0xAccfAc2339e16DC80c50d2fa81b5c2B049B4f947
ResolverMetadata 0xBF4543819ECede56220bcB1e8C1BBa9Ef290a58a

Deployments go through the Makefile, which validates the required parameters, records them in config/constants.json and then runs the matching hardhat-deploy script. Run make help for the full list of targets.

make deploy-settlement            # also: deploy-access-token, deploy-power-pod,
                                  # deploy-whitelist-registry, deploy-crosschain-whitelist,
                                  # deploy-resolver-metadata
make get OPS_NETWORK=mainnet PARAMETER=OPS_SETTLEMENT_ADDRESS   # read an address back out of deployments/

Parameters are read from a .env file as OPS_* variables. OPS_NETWORK and OPS_CHAIN_ID are always required; each target validates its own additions, so deploy-settlement, for example, also needs OPS_ROUTER_V6_ADDRESS, OPS_ACCESS_TOKEN_ADDRESS, OPS_WETH_ADDRESS and OPS_SETTLEMENT_OWNER_ADDRESS. Contracts are deployed through a CREATE3 deployer so that the same address is used on every chain, which needs OPS_CREATE3_DEPLOYER_ADDRESS and a salt; zkSync Era does not support CREATE3 and falls back to a plain deployment.

Audits

Audit reports for the Fusion contracts are published in 1inch/1inch-audits, under Fusion Settlement V2, Fusion mode and Token-plugins, and Fees for LO and Fusion V1.

Security

Please do not report vulnerabilities through public GitHub issues or pull requests.

More on how 1inch approaches security: 1inch.io/security.

Documentation

Contributing

Bug reports and pull requests are welcome. See CONTRIBUTING.md for the workflow, and make sure yarn lint and yarn test pass before opening a PR.

License

MIT, see LICENSE.md.

About

No description, website, or topics provided.

Resources

Contributing

Stars

67 stars

Watchers

7 watching

Forks

Releases

Packages

Used by

Contributors

Languages