Intent Engine
The intent engine is the core of Amish Protocol. It receives signed messages from borrowers and lenders, matches compatible pairs, and generates executable loan orders. Unlike pool-based systems where users interact with shared liquidity, Amish users express their terms as intents and wait for the protocol to find counterparties.
What is an intent
An intent is a signed message expressing willingness to borrow or lend under specific conditions. Intents do not lock capital. A user can create an intent, modify it, or cancel it at any time before a match forms. Capital commits only when both parties agree and execute their on-chain transfers.
This design shifts the commitment point. In pool-based protocols, lenders commit capital by depositing to a pool - they hope borrowers appear. In Amish, both parties commit simultaneously when a match is found. No capital sits idle waiting.
Borrow intents
A borrower creates an intent specifying what collateral they offer, what principal they want, and the terms they accept.
The key fields in a borrow intent:
Collaterals - The assets the borrower offers as collateral, including chain, contract address, and amount for each. A borrower can offer multiple collateral types across different chains in a single intent.
Accepted principals - The assets the borrower will accept as the loan principal and which chains they want to receive them on.
Minimum LTV - The minimum loan-to-value ratio the borrower requires, in basis points. A value of 7500 means the borrower wants at least 75% of their collateral value as loan principal.
Maximum APR - The highest interest rate the borrower will pay, in basis points. A value of 800 means 8% maximum.
Loan lifetime - How long the loan should last, in seconds. 2592000 seconds equals 30 days.
Payout address - Where the borrower wants to receive the principal. This can be a different address than the one signing the intent.
Signature proof - A cryptographic signature binding the intent to the borrower's address.
Example: A borrower offers 1 WETH on Ethereum as collateral, wants USDC on Arbitrum as principal, at minimum 75% LTV, maximum 8% APR, for 30 days.
Lend intents
A lender creates an intent specifying what principal they offer, what collateral they accept, and their required terms.
Principals - The assets the lender offers to lend, including chain, contract address, and amount for each.
Accepted collaterals - The collateral types the lender will accept. Lenders typically restrict this to assets they trust and can value reliably.
Maximum LTV - The highest loan-to-value ratio the lender will extend. Lower values indicate more conservative lending.
Minimum APR - The lowest interest rate the lender will accept.
Example: A lender offers 10,000 USDC on Arbitrum, accepts WETH or WBTC on Ethereum as collateral, at maximum 80% LTV, minimum 6% APR, for 30 days.
How matching works
The matching engine continuously scans for compatible intent pairs. Two intents match when their requirements overlap across four dimensions.
Asset compatibility - There must exist at least one collateral-principal pair that both parties accept. If the borrower offers WETH and wants USDC, and the lender offers USDC and accepts WETH, asset compatibility is satisfied.
LTV overlap - The borrower's minimum LTV must not exceed the lender's maximum. If the borrower wants at least 75% and the lender allows up to 80%, overlap exists at any value between 75% and 80%.
APR overlap - The borrower's maximum APR must meet or exceed the lender's minimum. If the borrower accepts up to 8% and the lender requires at least 6%, any rate between 6% and 8% works.
Duration match - Both parties must specify the same loan duration. Unlike LTV and APR where overlap suffices, duration must match exactly.
When all four conditions are satisfied, the engine computes effective terms. For LTV, the protocol uses the lower of the two limits to protect both parties. For APR, the protocol splits the difference between the borrower's maximum and lender's minimum.
Order generation
When a user submits an intent with multiple collateral types and multiple principal types, the protocol generates orders for every valid combination.
A borrower offering 3 collateral types and accepting 2 principal types generates 6 orders. Each order represents one specific collateral-principal pair with the same terms from the parent intent. The matching engine can match any of these orders independently.
Orders track their own fill state:
OPEN - Available for matching
PARTIALLY_FILLED - Some amount has been matched, remainder available
FILLED - Completely matched, no remaining amount
CANCELLED - User cancelled the order
This multi-order structure enables efficient capital allocation. A single lender intent can fill multiple borrower orders across different collateral types. A single borrower can receive principal from multiple lenders.
Partial fills
Large intents often match against multiple counterparties. The protocol tracks fill amounts per order, allowing partial matches.
Consider a lender offering 100,000 USDC. The matching engine might find three borrowers:
Borrower A wants 25,000 USDC at terms matching 7% APR
Borrower B wants 40,000 USDC at terms matching 7.5% APR
Borrower C wants 35,000 USDC at terms matching 6.8% APR
Each match creates a separate loan. The lender receives three debt tokens, one per loan, with independent terms and health factors. This design maximizes capital utilization while respecting each party's requirements.
Intent lifecycle
An intent progresses through five phases from submission to loan activation.
Submission - The user signs their intent and submits it to the Amish backend. The backend validates the signature, stores the intent, and generates orders. No capital locks at this stage.
Matching - The matching engine scans for compatible intents. When a match forms, the engine computes effective terms and creates a match record linking the two parties.
Commitment - The backend constructs a Merkle tree containing the matched transfers for the current epoch. It commits the Merkle root on-chain through the RootsManager contract.
Execution - Both parties execute their transfers by submitting Merkle proofs. The borrower deposits collateral to the CollateralManager. The lender transfers principal through the DebtIssuer.
Activation - Once both transfers confirm, the loan becomes active. The DebtIssuer mints an IssuedDebt ERC-20 token to the lender representing their claim on principal plus interest.
Loan statuses
Once created, a loan transitions through defined states:
PENDING_TRANSFER - Match found, waiting for on-chain transfers from both parties
ACTIVE - Funds settled, loan is running, interest accruing
REPAID - Borrower repaid principal plus interest, loan closed successfully
LIQUIDATED - Collateral value dropped, position was liquidated
DEFAULTED - Loan expired without repayment, collateral seized
FAILED - Initial transfers failed, loan never activated
Health monitoring
The protocol continuously monitors active loan health using a health score in basis points:
A health score of 15000 means the collateral is worth 150% of the debt. As collateral value drops or debt grows through accrued interest, the health score decreases.
Risk levels based on health score:
15000 or above (150%+) - Safe
11000 to 14999 (110-150%) - Warning, consider adding collateral
Below 11000 (under 110%) - Critical, approaching liquidation
Each loan references a liquidation rule that defines the exact threshold where liquidation becomes possible. When health drops below this threshold, liquidators can seize collateral to repay the debt.
Intent cancellation
Users can cancel unmatched intents at any time. Cancellation is instant for intents with only OPEN orders. Once an order is partially or fully filled, that specific order cannot be cancelled - the match has formed and the loan process has begun.
Unfilled orders from the same intent can still be cancelled even if other orders from that intent have matched.
Last updated