-
Notifications
You must be signed in to change notification settings - Fork 80
Output validator [OutputValidator v1.0.0] #1327
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
0xDEnYO
wants to merge
35
commits into
main
Choose a base branch
from
output-validator-lf-15125
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 11 commits
Commits
Show all changes
35 commits
Select commit
Hold shift + click to select a range
1d4a5f1
create new contract OutputValidator + tests + docs
0xDEnYO 98a74d4
deploy to OPT and ARB staging
0xDEnYO 2a7abcc
some smaller adjustments
0xDEnYO 8a7c1a1
add constructor parameter validation
0xDEnYO 2a9abaf
Update test/solidity/Periphery/OutputValidator.t.sol
0xDEnYO 74ddaf5
Merge branch 'main' of github.com:lifinance/contracts into output-val…
0xDEnYO 0c67927
Logic in OutputValidator updated
0xDEnYO dbd39aa
update conventions
0xDEnYO 8717c9b
update deploy requirements
0xDEnYO 48d9599
update deploy scripts
0xDEnYO f1c3e04
unit tests updated (100%)
0xDEnYO 7b2b1a0
add withdrawablePeriphery as parent contract
0xDEnYO a5dd76a
update deploy requirements
0xDEnYO 62e13ed
update deploy scripts
0xDEnYO 5223a5e
update docs
0xDEnYO 5e2770d
increase unit test coverage to 100%
0xDEnYO 30f2c31
some smaller changes
0xDEnYO 3a1d8fd
re-added complex test cases
0xDEnYO ca79be2
remove unnecessary content from docs file
0xDEnYO 34f69f9
Update docs/OutputValidator.md
0xDEnYO 9b41cef
Update src/Periphery/OutputValidator.sol
0xDEnYO 27c23fb
Update docs/OutputValidator.md
0xDEnYO e15e372
Merge branch 'main' of github.com:lifinance/contracts into output-val…
0xDEnYO 60ecd6a
Merge branch 'output-validator-lf-15125' of github.com:lifinance/cont…
0xDEnYO a558756
update comments
0xDEnYO 97b1893
harmonize tests
0xDEnYO c78d983
update logic in OutputValidator
0xDEnYO 4b50606
update docs
0xDEnYO 514f66c
deployed to OPT/ARB staging
0xDEnYO 9427846
updated unit test
0xDEnYO ab084c4
verify staging deployments
0xDEnYO 38e0ade
update unit tests
0xDEnYO 9cb5553
add outputValidator signatures to sigs.json
0xDEnYO 17231bf
Merge branch 'main' of github.com:lifinance/contracts into output-val…
0xDEnYO 3a1012a
remove duplicate entries from diamond logs
0xDEnYO File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,156 @@ | ||
| # OutputValidator | ||
|
|
||
| ## Overview | ||
|
|
||
| The `OutputValidator` contract is a periphery contract that validates swap output amounts and transfers excess tokens to a designated validation wallet. It is designed to be called by the Diamond contract after a swap operation to ensure that any excess output tokens are properly distributed. | ||
|
|
||
| ## Key Features | ||
|
|
||
| - **Excess Distribution Management**: Intelligently distributes excess tokens to validation wallet | ||
| - **Dual Token Support**: Handles both native (ETH) and ERC20 tokens with separate functions | ||
| - **No Ownership**: Stateless design without ownership requirements | ||
| - **Gas Optimized**: Minimal validation for maximum efficiency | ||
|
|
||
| ## Contract Logic | ||
|
|
||
| ### Native Token Flow | ||
|
|
||
| 1. The calling contract (Diamond) sends a portion of native tokens as `msg.value` for excess handling | ||
| 2. **Calculates excess**: `excessAmount = (contract_balance + msg.value) - expectedAmount` | ||
| 3. **Smart distribution**: | ||
| - If `excessAmount >= msg.value`: All `msg.value` goes to validation wallet (contract balance covers expected amount) | ||
| - If `excessAmount < msg.value`: Sends `excessAmount` to validation wallet, returns `msg.value - excessAmount` to sender | ||
| 4. **User receives expected amount** through the normal swap flow, not from this contract | ||
|
|
||
| ### ERC20 Token Flow | ||
|
|
||
| 1. The calling contract (Diamond) must have sufficient ERC20 token balance and approve this contract | ||
| 2. **Calculates excess**: `excessAmount = ERC20(tokenAddress).balanceOf(msg.sender) - expectedAmount` | ||
| 3. **Transfer excess**: If `excessAmount > 0`, transfers excess tokens to validation wallet via `transferFrom` | ||
| 4. **Safety checks**: Validates wallet address and handles zero excess gracefully | ||
|
|
||
| > **Design Philosophy**: The contract handles excess distribution only. Users receive their `expectedAmount` through the primary swap mechanism, while this contract ensures proper excess management without holding funds permanently. | ||
|
|
||
| **Note**: The contract reverts on arithmetic underflow if actual amounts are less than expected, providing fail-safe behavior. | ||
|
|
||
| ## Functions | ||
|
|
||
| ### `validateNativeOutput` | ||
|
|
||
| ```solidity | ||
| function validateNativeOutput( | ||
| uint256 expectedAmount, | ||
| address validationWalletAddress | ||
| ) external payable | ||
| ``` | ||
|
|
||
| **Parameters:** | ||
|
|
||
| - `expectedAmount`: The expected amount of native tokens (minAmountOut) | ||
| - `validationWalletAddress`: The address to send excess tokens to | ||
|
|
||
| **Behavior:** | ||
|
|
||
| - Calculates total output as `contract_balance + msg.value` | ||
| - Intelligently distributes excess between validation wallet and sender | ||
| - Designed for scenarios where `msg.value` represents a portion sent for excess handling | ||
0xDEnYO marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ### `validateERC20Output` | ||
|
|
||
| ```solidity | ||
| function validateERC20Output( | ||
| address tokenAddress, | ||
| uint256 expectedAmount, | ||
| address validationWalletAddress | ||
| ) external | ||
| ``` | ||
|
|
||
| **Parameters:** | ||
|
|
||
| - `tokenAddress`: The address of the ERC20 token to validate | ||
| - `expectedAmount`: The expected amount of tokens (minAmountOut) | ||
| - `validationWalletAddress`: The address to send excess tokens to | ||
|
|
||
| **Behavior:** | ||
|
|
||
| - Checks caller's token balance and calculates excess | ||
| - Transfers excess to validation wallet if `excessAmount > 0` | ||
| - Validates wallet address and requires sufficient allowance | ||
|
|
||
| ## Errors | ||
|
|
||
| The contract does not define custom errors. Error handling is delegated to the underlying libraries: | ||
|
|
||
| - **Native token errors**: Handled by `LibAsset.transferAsset()` | ||
| - **ERC20 token errors**: Handled by `SafeTransferLib.safeTransferFrom()` | ||
| - **Input validation**: Handled by `LibAsset` library for null address checks | ||
|
|
||
| ## Integration | ||
|
|
||
| ### Example Usage | ||
|
|
||
| ```solidity | ||
| // For native tokens - send portion of output for excess handling | ||
| outputValidator.validateNativeOutput{value: portionForExcess}( | ||
| expectedAmount, | ||
| validationWallet | ||
| ); | ||
|
|
||
| // For ERC20 tokens | ||
| // First approve the OutputValidator to spend excess tokens | ||
| token.approve(address(outputValidator), excessAmount); | ||
| outputValidator.validateERC20Output( | ||
| address(token), | ||
| expectedAmount, | ||
| validationWallet | ||
| ); | ||
| ``` | ||
|
|
||
| ## Security Considerations | ||
|
|
||
| - **Stateless Design**: No ownership or state storage reduces attack surface | ||
| - **Safe Transfers**: Uses `SafeTransferLib` for safe ERC20 operations and `LibAsset` for native transfers | ||
| - **Input Validation**: ERC20 function validates wallet addresses; native transfers rely on `LibAsset` validation | ||
| - **Fail-Safe Behavior**: Reverts on arithmetic underflow when actual < expected amounts | ||
| - **No Fund Retention**: Contract never retains funds permanently, minimizing risk | ||
|
|
||
| ## Test Coverage | ||
|
|
||
| The contract includes comprehensive test coverage including: | ||
|
|
||
| ### **Core Functionality Tests** | ||
|
|
||
| - Native token validation with excess (positive slippage scenarios) | ||
| - ERC20 token validation with excess (positive slippage scenarios) | ||
| - Edge cases (zero expected amount, insufficient allowance) | ||
|
|
||
| ### **Integration Tests** | ||
|
|
||
| - Complete DEX swap + OutputValidator + Bridge flows | ||
| - ERC20 → ERC20 swap with positive slippage | ||
| - ERC20 → Native swap with positive slippage | ||
| - Native → ERC20 swap with positive slippage | ||
|
|
||
| ### **Negative Test Cases** | ||
|
|
||
| - Insufficient allowance scenarios | ||
| - Native transfer failures to invalid addresses | ||
| - Zero value with non-zero expected amount | ||
| - **No excess scenarios** (contract handles gracefully by transferring 0 tokens) | ||
|
|
||
| ### **Test Statistics** | ||
|
|
||
| - **19 test cases** covering all code paths | ||
| - **All branches covered** including edge cases | ||
| - **Realistic scenarios** using MockDEX and Diamond integration | ||
|
|
||
| ## Deployment | ||
|
|
||
| The contract is deployed using the standard deployment script pattern with no constructor parameters. The contract is automatically included in periphery contract deployments and is configured in `script/deploy/resources/deployRequirements.json`. | ||
|
|
||
| ### **Deployment Scripts** | ||
|
|
||
| - **Standard**: `script/deploy/facets/DeployOutputValidator.s.sol` | ||
| - **zkSync**: `script/deploy/zksync/DeployOutputValidator.zksync.s.sol` | ||
|
|
||
| Both scripts follow the established deployment patterns and integrate with the CREATE3Factory for predictable contract addresses. No configuration parameters are required due to the stateless design. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| // SPDX-License-Identifier: LGPL-3.0-only | ||
| pragma solidity ^0.8.17; | ||
|
|
||
| import { DeployScriptBase } from "./utils/DeployScriptBase.sol"; | ||
| import { OutputValidator } from "lifi/Periphery/OutputValidator.sol"; | ||
|
|
||
| contract DeployScript is DeployScriptBase { | ||
| constructor() DeployScriptBase("OutputValidator") {} | ||
|
|
||
| function run() public returns (OutputValidator deployed) { | ||
| deployed = OutputValidator(deploy(type(OutputValidator).creationCode)); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| // SPDX-License-Identifier: LGPL-3.0-only | ||
| pragma solidity ^0.8.17; | ||
|
|
||
| import { DeployScriptBase } from "./utils/DeployScriptBase.sol"; | ||
| import { OutputValidator } from "lifi/Periphery/OutputValidator.sol"; | ||
|
|
||
| contract DeployScript is DeployScriptBase { | ||
| constructor() DeployScriptBase("OutputValidator") {} | ||
|
|
||
| function run() public returns (OutputValidator deployed) { | ||
| deployed = OutputValidator(deploy(type(OutputValidator).creationCode)); | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.