Escrow
Overview
The Escrow contract allows users to lock ERC-20 tokens in order to receive off-chain payments. Users deposit tokens specifying:
Which off-chain payment verifiers they accept.
Conversion rates for various fiat currencies.
A gating service (optional) that can sign a userβs intent to claim funds.
When a taker signals an intent to pay off-chain, they specify how many tokens they want to claim and through which payment verifier. Upon proving the off-chain payment has occurred (by calling fulfillIntent
), the escrow releases the on-chain tokens to the taker (minus applicable fees).
Constants
uint256 internal constant PRECISE_UNIT = 1e18;
uint256 constant CIRCOM_PRIME_FIELD = ...;
uint256 constant MAX_SUSTAINABILITY_FEE = 5e16; // 5%
State Variables
uint256 public immutable chainId;
The chain ID where this contract is deployed.mapping(address => uint256[]) public accountDeposits;
Which deposits belong to a given address.mapping(address => bytes32) public accountIntent;
Tracks a single active intent for each address.mapping(uint256 => mapping(address => DepositVerifierData)) public depositVerifierData;
Links a deposit ID + verifier to the relevant verification data (e.g., payee details).mapping(uint256 => address[]) public depositVerifiers;
Lists all verifiers associated with a deposit.mapping(uint256 => mapping(address => mapping(bytes32 => uint256))) public depositCurrencyConversionRate;
For a given deposit ID and verifier, maps fiat currency -> conversion rate.mapping(uint256 => mapping(address => bytes32[])) public depositCurrencies;
For a given deposit ID and verifier, stores an array of fiat currencies.mapping(uint256 => Deposit) public deposits;
The core deposit data.mapping(bytes32 => Intent) public intents;
All signaled intents (by their intent hash).Whitelist / Governance
bool public acceptAllPaymentVerifiers;
mapping(address => bool) public whitelistedPaymentVerifiers;
mapping(address => uint256) public paymentVerifierFeeShare;
uint256 public intentExpirationPeriod;
After which an intent is considered expired.uint256 public sustainabilityFee;
Fee (inPRECISE_UNIT
terms) taken from each successful intent fulfillment.address public sustainabilityFeeRecipient;
Where the sustainability fee is sent.uint256 public depositCounter;
Incremented to create unique deposit IDs.
Constructor
Parameters:
_owner
: The address to set as the contract owner (can pause, unpause, and manage verifiers)._chainId
: The chain ID for which this escrow is valid._intentExpirationPeriod
: Time (in seconds) after which an open intent can be pruned._sustainabilityFee
: Percentage (in 1e18 precision) charged upon successful intent fulfillment._sustainabilityFeeRecipient
: Address to receive the sustainability fees.
Transfers ownership to _owner
and sets initial contract state.
External Functions
createDeposit
Description:
Deposits _amount
of _token
into escrow. You specify:
A range of intent sizes (
_intentAmountRange
).Which verifiers (
_verifiers
) the deposit will accept.Gating + payee details for each verifier (
_verifierData
).Which currencies (and rates) each verifier can handle (
_currencies
).
Requirements:
User must have approved this contract to transfer
_amount
of_token
.The deposit is unique (each call yields a new
depositId
)._amount
must be >=min
of_intentAmountRange
._verifiers
length must match_verifierData
and_currencies
length.Each verifier must be whitelisted or
acceptAllPaymentVerifiers
must betrue
.Each currencyβs
conversionRate
must be > 0.
Effects:
Increments
depositCounter
.Stores the deposit data.
Locks the tokens in this contract.
Emits
DepositReceived
andDepositVerifierAdded
(andDepositCurrencyAdded
) events.
signalIntent
Description: A taker declares an intent to pay the depositβs off-chain counterpart. This:
Ensures the deposit is still
acceptingIntents
.Validates
_amount
against depositβs range.Optionally checks a gating service signature.
Reserves
_amount
from the depositβsremainingDeposits
.Records a new
Intent
inintents
.
Requirements:
Caller must not have another active
Intent
(accountIntent[msg.sender] == 0
)._amount
is within the depositβsintentAmountRange
._fiatCurrency
is recognized indepositCurrencyConversionRate[_depositId][_verifier]
.
Effects:
May prune expired intents if liquidity is insufficient.
Emits
IntentSignaled
upon success.
cancelIntent
Description:
Allows the intent owner to cancel an intent. This frees up the escrowed amount.
Reverts if msg.sender
is not the intent owner.
fulfillIntent
Description: Attempts to prove that the off-chain payment has been made according to the associated payment verifier. On success:
The escrowed tokens are transferred to the specified
to
address.Fees are taken out for sustainability and optionally the payment verifier.
Parameters:
_paymentProof
β The proof data for verifying off-chain payment (e.g., TLSNotary, ZK, etc.)._intentHash
β The ID of the signaled intent.
Reverts if:
The verifier check fails.
The
_intentHash
does not match the proofβs extracted intent hash.
Emits:
IntentFulfilled
event.
releaseFundsToPayer
Description:
Allows the deposit owner (not the intent owner) to push funds to the off-chain payerβs to
address, effectively acknowledging the payment or an alternative arrangement.
Effects:
Removes the intent from state.
Transfers tokens to the
intent.owner
orintent.to
.Emits
IntentFulfilled
event with zero verifier address.
updateDepositConversionRate
Description: The depositor can adjust the depositβs conversion rate for a specific currency and verifier. Only future intents will be affected; existing ones store the old rate.
withdrawDeposit
Description: Withdraws any unencumbered tokens from the deposit. Prunes any expired intents (making more tokens claimable). If no tokens remain (and no open intents), the deposit is fully closed and removed.
Governance Functions
addWhitelistedPaymentVerifier
Adds a payment verifier to the whitelist, with a certain _feeShare
.
removeWhitelistedPaymentVerifier
Removes a verifier from the whitelist.
updatePaymentVerifierFeeShare
Updates the fee share for a given whitelisted verifier.
updateAcceptAllPaymentVerifiers
Toggles whether any verifier address can be used (bypassing the whitelist).
setSustainabilityFee
Sets the global sustainability fee (max 5%). Fee is taken upon intent fulfillment.
setSustainabilityFeeRecipient
Sets the address receiving protocol fees.
setIntentExpirationPeriod
Updates how long an intent remains valid before it can be pruned.
pauseEscrow / unpauseEscrow
Pauses or unpauses the contractβs core functions:
Paused: Creates deposit, updates conversion rate, signals/fulfills intent are disabled.
Unpaused: Resumes all functionalities.
External View Functions
getPrunableIntents
Returns a list of expired (prunable) intent hashes for a deposit and the total amount they occupy.
getDeposit
Returns a DepositView, including:
The deposit details.
Available liquidity (accounting for expired intents).
Associated verifiers/currency data.
getAccountDeposits
Returns the set of deposits belonging to _account
.
getDepositFromIds
Returns the DepositView[]
for a given list of deposit IDs (part of IEscrow interface).
getIntent
Provides the IntentView, linking the intent to its deposit.
getIntents
Batch retrieval of multiple intents.
getAccountIntent
Returns the active intent (if any) for a given account.
Last updated