██╗ ███████╗██╗ ██╗███████╗███████╗██████╗ ███████╗██╗ ██╗
██║ ██╔════╝ ██║ ██╔╝██╔════╝██╔════╝██╔══██╗██╔══██║██║ ██║
██║ █████╗ ╚██╔╝ ███████╗██║ ██████╔╝██║ ██║██║ █╗ ██║
██║ ██╔══╝ ██╔╝██╗ ╚════██║██║ ██╔══██╗██║ ██║██║███╗██║
███████╗███████╗██║ ██╗███████║███████╗██║ ██║███████║╚███╔███╔╝
╚══════╝╚══════╝╚═╝ ╚═╝╚══════╝╚══════╝╚═╝ ╚═╝╚══════╝ ╚══╝╚══╝
///Immutable, non-custodial, conditional smart contract escrow.
╚═══════╝ ╚═╝ ╚═══════╝ ╚════════╝ ╚═══╝ ╚══════╝ ╚════╝
Immutable, non-custodial, flexibly-conditioned escrow, transfers, and swaps.
All LeXscroW types have the following features:
- Ownerless unique contract deployment
- Optional conditions for execution, including signatures, time, oracle-fed data, and more, which are immutable from construction and may be combined
- specify depositing part(ies) or allow any address to deposit (open offer)
- parties may replace their own address, and may be an EOA or a contract
- mutual early termination option
- expiration denominated in seconds / Unix time
- re-usable until expiration
As all parameters aside from parties' addresses are immutable upon a LeXscroW's deployment, configuration of each such parameter is critical.
Below is some basic information on each type of LeXscroW. For more details, please consult the documentation.
README
LICENSE
└─ docs
├─_overview.mdx
├─_design.mdx
├─_deploy.mdx
└─_use.mdx
└─ src
├─ DoubleTokenLexscrow.sol
├─ DoubleTokenLexscrowFactory.sol
├─ EthLexscrow.sol
├─ EthLexscrowFactory.sol
├─ TokenLexscrow.sol
├─ TokenLexscrowFactory.sol
└─ libs
└─ LexscrowConditionManager.sol
└─ test
├─ DoubleTokenLexscrow.t.sol
├─ DoubleTokenLexscrowFactory.t.sol
├─ EthLexscrow.t.sol
├─ EthLexscrowFactory.t.sol
├─ LexscrowConditionManager.t.sol
├─ TokenLexscrow.t.sol
└─ TokenLexscrowFactory.t.solConditional Atomic Token Swaps
Bilateral smart escrow contract for (non-fee-on-transfer, non-rebasing) ERC20 tokens.
-
buyer(or, if an open offer, any address) depositstoken1andseller(or if an open offer, any address) depositstoken2viadepositTokens()ordepositTokensWithPermit() -
if desired,
buyermay replace its address by passing the new address toupdateBuyer(), andsellermay do the same withupdateSeller() -
parties may choose to mutually terminate early by passing
truetoelectToTerminate(); if both do so, their deposited tokens will be returned and the LeXscroW will be expired -
execute()is not permissioned, and thus may be called by any address. If called, the LeXscrow executes and simultaneously releasestotalAmount1oftoken1tosellerandtotalAmount2oftoken2tobuyeriff:(1)
buyerandsellerhave respectively depositedtotalAmount1+ any applicablefee1oftoken1andtotalAmount2+ any applicablefee2oftoken2,(2)
expirationTime>block.timestamp, and(3) if there is/are condition(s), such condition(s) is/are satisfied upon the external call in
execute().
If executed, the LeXscroW is re-usable by parties until the set expiration time.
Otherwise, all deposited amounts of token1 are returned to buyer and all deposited amounts of token2 are returned to seller if the LeXscroW expires.
Conditional Token Payments
Unilateral smart escrow contract for (non-fee-on-transfer, non-rebasing) ERC20 tokens.
-
initialized with a
depositamount which can be any amount up to thetotalAmount, and may be refundable or non-refundable tobuyerupon expiry -
buyer(or, if an open offer, any address) deposits viadepositTokens()ordepositTokensWithPermit() -
if desired,
buyermay replace its address by passing the new address toupdateBuyer(), andsellermay do the same withupdateSeller() -
sellermay callrejectDepositor()to reject a depositing address, which will cause any amount deposited by such address to become withdrawable (viawithdraw()) by the rejected depositor. Also enables early mutual termination. -
execute()is not permissioned, and thus may be called by any address. If called, the LeXscroW executes and simultaneously releasestotalAmounttoselleriff:(1)
buyerhas depositedtotalAmount+ any applicablefeenet of anypendingWithdrawamount,(2)
expirationTime>block.timestamp,(3) if there is/are condition(s), such condition(s) is/are satisfied upon the external call in
execute().
If executed, the LeXscroW is re-usable by parties until the set expiration time.
Otherwise, amount held in the LeXscroW will be treated according to the code in checkIfExpired() when called following expiry. If expired, the applicable party must call withdraw() to receive their tokens.
Conditional Gas Token Transfers
Unilateral smart escrow contract for native gas tokens, denominated in 1e18 decimals (wei).
-
initialized with a
depositamount which can be any amount up to thetotalAmount, and may be refundable or non-refundable tobuyerupon expiry -
buyer(or, if an open offer, any address) deposits by sending amount directly to the LeXscroW contract address and thus invoking thereceive()function. The conditional logic rejects any amount in excess oftotalWithFee -
if desired,
buyermay replace its address by passing the new address toupdateBuyer(), andsellermay do the same withupdateSeller() -
sellermay callrejectDepositor()to reject a depositing address, which will cause any amount deposited by such address to become withdrawable (viawithdraw()) by the rejected depositor. Also enables early mutual termination. -
execute()is not permissioned, and thus may be called by any address. If called, the LeXscroW executes and simultaneously releasestotalAmounttoselleriff:(1)
buyerhas depositedtotalAmount+ any applicablefeenet of anypendingWithdrawamount,(2)
expirationTime>block.timestamp, and(3) if there is/are condition(s), such condition(s) is/are satisfied upon the external call in
execute().
If executed, the LeXscroW is re-usable by parties until the set expiration time.
Otherwise, amount held in the LeXscroW will be treated according to the code in checkIfExpired() when called following expiry. If expired, the applicable party must call withdraw() to receive their funds.
-
DoubleTokenLexscrowFactory,TokenLexscrowFactory, andEthLexscrowFactoryset any applicable fee amounts, fee receiver address, and enable easy deployment of the corresponding LeXscroW type (including simultaneous deployment of a Ricardian Tripler and a corresponding LeXscroW where supported). -
LexscrowConditionManageris an adaptation of the BORG-COREConditionManager, without auth/access control (and thus also the ability to add or remove conditions post-deployment) in favor of immutability.
Before you begin, ensure you have the following installed:
To set up the project locally, follow these steps:
-
Clone the repository
git clone https://github.com/MetaLex-Tech/LeXscroW cd LeXscroW -
Install dependencies
foundryup # Update Foundry tools forge install # Install project dependencies
-
Compile Contracts
forge build