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.
- 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.
- A resolver calls
fillOrderon the Limit Order Protocol.SimpleSettlementcomputes the price for the current block through_getMakingAmount/_getTakingAmount, applying the auction rate bump encoded in the order'sauctionDetails. - 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.
- 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.
- On Ethereum mainnet the
Settlementcontract 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.
| 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/.
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
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 NatSpecCI 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-settlementIt ships the contract sources, the interfaces, and the order-building helpers in test/helpers.
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.
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.
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.
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.
Please do not report vulnerabilities through public GitHub issues or pull requests.
More on how 1inch approaches security: 1inch.io/security.
- Fusion swap introduction — protocol documentation
- 1inch Developer Portal — the API resolvers and integrators build against
- Limit Order Protocol — the order format and fill mechanics Fusion extends
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.
MIT, see LICENSE.md.