Conversation
… received tokens across all deposit paths
### Summary of Changes
Addresses the **High** severity security audit finding in `evm-gateway-contracts` (Cat 12: Concurrency & transactional integrity) by enforcing Checks-Effects-Interactions (CEI) and validating received token amounts across all deposit vectors in `Deposits.sol`[cite: 31].
---
### Vulnerability Analysis
- In `src/modules/wallet/Deposits.sol`, the internal functions `_depositWithApproval`, `_depositWithPermit`, and `_depositWithAuthorization` previously updated internal state (`_increaseAvailableBalance`) **prior** to executing the external token transfer[cite: 31].
- For deflationary, fee-on-transfer, or non-standard ERC-20 tokens, the depositor was credited with the nominal requested amount while the contract received less[cite: 31]. The unbacked shortfall became redeemable from other users' deposits during subsequent withdrawals[cite: 31].
- The effects-before-interactions pattern also permitted reentrancy via ERC-777 or ERC-1363 token callbacks, enabling callers to observe an inflated balance before funds were safely transferred[cite: 31].
- In the initial remediation draft, `_depositWithAuthorization` sampled `balanceBefore` **after** invoking `receiveWithAuthorization`, calculating `received = 0` and causing all authorization-based deposits to revert with `UnsupportedTokenTransferFee`.
---
### Key Remediations
1. **Checks-Effects-Interactions Enforcement:**
- Reordered operations across `_depositWithApproval`, `_depositWithPermit`, and `_depositWithAuthorization`:
1. Pre-transfer balance snapshot (`balanceBefore = balanceOf(address(this))`).
2. Execute external transfer (`safeTransferFrom` or `receiveWithAuthorization`)[cite: 31, 50].
3. Delta measurement (`received = balanceOf(address(this)) - balanceBefore`)[cite: 50].
4. Enforce strict parity: revert with `UnsupportedTokenTransferFee()` if `received != value`[cite: 31, 50].
5. State update (`_increaseAvailableBalance`) and event emission (`emit Deposited`)[cite: 50, 51].
2. **Timing Correction in `_depositWithAuthorization`:**
- Moved the `balanceBefore` capture ahead of `receiveWithAuthorization` to guarantee proper balance accounting and eliminate the false-positive fee revert.
---
### Verification
- Compiled using `solc 0.8.29` via standard-JSON compiler driver: **0 errors, 0 warnings** across the 24-file import closure.
- Conforms to OpenZeppelin `SafeERC20` best practices[cite: 62].
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary of Changes
Addresses the High severity security audit finding in
evm-gateway-contracts(Cat 12: Concurrency & transactional integrity) by enforcing Checks-Effects-Interactions (CEI) and validating received token amounts across all deposit vectors inDeposits.sol[cite: 31].Vulnerability Analysis
src/modules/wallet/Deposits.sol, the internal functions_depositWithApproval,_depositWithPermit, and_depositWithAuthorizationpreviously updated internal state (_increaseAvailableBalance) prior to executing the external token transfer[cite: 31]._depositWithAuthorizationsampledbalanceBeforeafter invokingreceiveWithAuthorization, calculatingreceived = 0and causing all authorization-based deposits to revert withUnsupportedTokenTransferFee.Key Remediations
_depositWithApproval,_depositWithPermit, and_depositWithAuthorization: 1. Pre-transfer balance snapshot (balanceBefore = balanceOf(address(this))). 2. Execute external transfer (safeTransferFromorreceiveWithAuthorization)[cite: 31, 50]. 3. Delta measurement (received = balanceOf(address(this)) - balanceBefore)[cite: 50]. 4. Enforce strict parity: revert withUnsupportedTokenTransferFee()ifreceived != value[cite: 31, 50]. 5. State update (_increaseAvailableBalance) and event emission (emit Deposited)[cite: 50, 51]._depositWithAuthorization:balanceBeforecapture ahead ofreceiveWithAuthorizationto guarantee proper balance accounting and eliminate the false-positive fee revert.Verification
solc 0.8.29via standard-JSON compiler driver: 0 errors, 0 warnings across the 24-file import closure.SafeERC20best practices[cite: 62].