diff --git a/README.md b/README.md index 996a4f3a..199f9838 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Tokenlon is a decentralized exchange and payment settlement protocol based on bl ## Architecture -Under construction +![Tokenlon Architecture](./Tokenlon-Architecture.png) ## Deployed contracts diff --git a/Tokenlon-Architecture.png b/Tokenlon-Architecture.png new file mode 100644 index 00000000..9874bbab Binary files /dev/null and b/Tokenlon-Architecture.png differ diff --git a/doc/AllowanceTarget.md b/doc/AllowanceTarget.md new file mode 100644 index 00000000..c2f77508 --- /dev/null +++ b/doc/AllowanceTarget.md @@ -0,0 +1,7 @@ +# AllowanceTarget + +The AllowanceTarget contract manages token allowances and authorizes specific spenders to transfer tokens on behalf of users. + +## Security Considerations + +AllowanceTarget provides a pause mechanism to prevent unexpected situations. Only the contract owner can pause or unpause the contract. In most cases, the contract will not be paused. diff --git a/doc/CoordinatedTaker.md b/doc/CoordinatedTaker.md index 5894dcfe..aa81dc9b 100644 --- a/doc/CoordinatedTaker.md +++ b/doc/CoordinatedTaker.md @@ -1,3 +1,3 @@ # CoordinatedTaker -CoordinatedTaker is a conditional taker contract of LimitOrderSwap. It adds a fill permission design on the top of it. A permission of fill is issued by a coordinator with signature. If a user wants to fill an order, he needs to apply for the fill permission and submit the fill with it. The coordinator will manage the avaliable amount of each orders and only issue fill permission when the pending avaliable amount is enough. It helps avoiding fill collision and makes off-chain order canceling possible. +CoordinatedTaker is a conditional taker contract of LimitOrderSwap. It adds a fill permission design on the top of it. A permission of fill is issued by a coordinator with signature. If a user wants to fill an order, he needs to apply for the fill permission and submit the fill with it. The coordinator will manage the available amount of each orders and only issue fill permission when the pending available amount is enough. It helps avoiding fill collision and makes off-chain order canceling possible. diff --git a/doc/GenericSwap.md b/doc/GenericSwap.md index 647d812c..96ec69cf 100644 --- a/doc/GenericSwap.md +++ b/doc/GenericSwap.md @@ -1,7 +1,11 @@ # GenericSwap -GenericSwap is a general token swapping contract that integrate with different strategy executors. The GS contract is responsible for ensuring the result of a swap is match the order. However, the actual swap is executed by a strategy executor. This design allows fulfilling an order with any combination of swapping protocols. Also, by adjusting payload in off-chain system, it may support new protocol without upgrading contracts. +GenericSwap is a general token swapping contract designed to integrate with various strategy executors (e.g. the `SmartOrderSwap` contract). The GenericSwap contract is responsible for ensuring a result of a swap is match the order. However, the actual swap is executed by a strategy executor. This design allows fulfilling an order with any combination of swapping protocols. Also, by adjusting payload in our off-chain system, it may support new protocol without upgrading contracts. + +## Gas Saving Technique + +GenericSwap retains 1 wei of the maker token at the end of each swap transaction. This practice avoids repeatedly clearing the token balance to zero, as the EVM charges different gas fees for various storage states. By preventing frequent resets to zero, this approach effectively reduces gas consumption. ## Relayer -GS supports submitting a swap by a relayer with user signature. The hash of relayed swap should be recoreded to prevent replay attack. +The GenericSwap contract allows for trade submissions by a relayer with user's signatures. To prevent replay attacks, the hash of the relayed trade is recorded. diff --git a/doc/LimitOrderSwap.md b/doc/LimitOrderSwap.md index adba10c4..0eecaeb1 100644 --- a/doc/LimitOrderSwap.md +++ b/doc/LimitOrderSwap.md @@ -6,12 +6,12 @@ A taker can optionally provide extra action parameter in payload which will be e ## FullOrKill -The default `fillLimitOrder` function allows the settled taking amount is less than a taker requested. The reason is that it may not be sufficient for the whole request when a trade is actual executed and the rest available taking amout would be the actual taking amount in that case. If a taker wants a non-adjustable taking amount, then the `fillLimitOrderFullOrKill` function should be called instead. +The default `fillLimitOrder` function allows the settled taking amount is less than a taker requested. The reason is that it may not be sufficient for the whole request when a trade is actual executed and the rest available taking amount would be the actual taking amount in that case. If a taker wants a non-adjustable taking amount, then the `fillLimitOrderFullOrKill` function should be called instead. ## GroupFill -If a group of orders can be fulfilled by each other, then no external liquiditiy is needed for settling those orders. A user can spot this kind of group with profits so it would be the incentive of searching and submitting it. In some cases, a user may need to add some external liquidity or create some orders so the group can be formed and settled. +If a group of orders can be fulfilled by each other, then no external liquidity is needed for settling those orders. A user can spot this kind of group with profits so it would be the incentive of searching and submitting it. In some cases, a user may need to add some external liquidity or create some orders so the group can be formed and settled. ## Fee -Some portion of maker asset of an order will be deducted as protocol fee. The fee will be transfered to `feeCollector` during the settlement. Each order may have different fee factor, it depends on the characteristic of an order. +Some portion of maker asset of an order will be deducted as protocol fee. The fee will be transferred to `feeCollector` during the settlement. Each order may have different fee factor, it depends on the characteristic of an order. diff --git a/doc/RFQ.md b/doc/RFQ.md index 450c6b03..5e4d2590 100644 --- a/doc/RFQ.md +++ b/doc/RFQ.md @@ -1,18 +1,26 @@ # RFQ -RFQ (Request For Quote) is a contract that settles a trade between two parties. Normally it requires an off-chain quoting system which provides quotes and signatures from certain makers. A user may request for a quote of a specific trading pair and size. Upon receiving the request, any maker willing to trade can respond with a quote to the user. If the user accepts it, then both parties will sign the trading order and submit the order with signatures to the RFQ contract. After verifying signatures, the RFQ contract will transfer tokens between user and maker accordingly. +The RFQ (Request For Quote) contract facilitates the settlement of trades between two parties: a market maker and an user. We provide an off-chain quoting system that handles the quoting process. Users can request quotes for specific trading pairs and sizes. Upon receiving a request, any interested maker can provide a quote to the user. If the user accepts the quote, both parties will sign the trading order and submit it ot the RFQ contract along with their signatures. The RFQ contract verifies the signatures and executes the token transfers between the user and the market maker. ## Order option flags -There are two options that the maker of a RFQ offer can set. The option flags is a uint256 field in the offer. +The maker of an RFQ offer can specify certain options using a `uint256` field in the offer, referred to as option flags: -- Partial fill : Whether the Offer can be filled partially or not (but once). -- Contract call : Whether the Offer can be filled by a contract or not. +- `FLG_ALLOW_CONTRACT_SENDER` : Determines whether an RFQ offer can be filled by a contract. This flag is intended to prevent arbitrageurs from using contracts to execute flash loans to arbitrage RFQ orders. +- `FLG_ALLOW_PARTIAL_FILL`: Determines whether an RFQ offer can be partially filled. However, each RFQ order can only be filled once, regardless of whether it's fully or partially filled. +- `FLG_MAKER_RECEIVES_WETH` : Specifies whether a market maker wants the RFQ contract to wrap the ETH he received into WETH for him. ## Relayer -RFQ supports submitting a trade by a relayer with user signature. The hash of relayed trade should be recoreded to prevent replay attack. +The RFQ contract allows for trade submissions by a relayer with user's signatures. To prevent replay attacks, the hash of the relayed trade is recorded. ## Fee -Some portion of maker asset of an order will be deducted as protocol fee. The fee will be transfered to `feeCollector` during the settlement. Each order may have different fee factor, it depends on the characteristic of an order. +A portion of the maker's asset in the order will be deducted as a protocol fee. This fee is transferred to the `feeCollector` during settlement. + +The fee factor is composed of two parts: + +1. Protocol Fee +2. Gas Fee + +If a trade is submitted by a relayer, the relayer will adjust the gas fee according to the on-chain conditions at the time of the transaction. diff --git a/doc/SmartOrderStrategy.md b/doc/SmartOrderStrategy.md index 8502b1d7..016bbd3f 100644 --- a/doc/SmartOrderStrategy.md +++ b/doc/SmartOrderStrategy.md @@ -1,3 +1,7 @@ # SmartOrderStrategy -SmartOrderStrategy is a strategy executor of a generic swap. It should be called by GenericSwap contract and preform any swaps according to provided payload. This contract should not has any balance or token approval since it could perform any arbitary calls. Also the `executeStrategy` function is only allowed to be called by GenericSwap contract. +`SmartOrderStrategy` is a strategy executor of a generic swap. It is designed to be called by the `GenericSwap` contract and performs swaps according to the provided payload. This contract should not hold any significant token balance or require token approvals, as it can execute arbitrary calls. Additionally, the `executeStrategy` function is restricted to being called only by the `GenericSwap` contract. + +## Gas Saving Technique + +`SmartOrderStrategy` retains 1 wei of the maker token at the end of each swap transaction. This practice avoids repeatedly clearing the token balance to zero, as the EVM charges different gas fees for various storage states. By preventing frequent resets to zero, this approach effectively reduces gas consumption. diff --git a/doc/TokenCollector.md b/doc/TokenCollector.md index 5be84641..a5a8cce2 100644 --- a/doc/TokenCollector.md +++ b/doc/TokenCollector.md @@ -1,6 +1,8 @@ # TokenCollector -In Tokenlon V6, multiple schemes of token approval is supported. TokenCollector is an abstract contract that handles different ways of token transfering. When interacting with Tokenlon, user can choose one of supported approving scheme and prepare the corresponded Tokenlon permit parameter (in bytes). The first byte of the permit indicate the type and the rest are encoded data with type specific structure. +`TokenCollector` is an abstract contract designed to handle various token collection mechanisms. It supports different methods of token transfer across different token standards. Users have great flexibility in token authorization when interacting with Tokenlon. + +When interacting with Tokenlon, users can select one of the supported approval schemes and provide the corresponding parameters in the data field (encoded as type `bytes`). The first byte of this data indicates the type of the scheme, followed by the encoded data specific to that type. ``` // ***********************************