fix: security audit fixes for TokenStandardIntrospection.sol#39
Open
rroland10 wants to merge 1 commit into
Open
Conversation
Address five vulnerabilities found during security audit: - V-TSI-01 (HIGH): Fix deposit overwrite — changed `=` to `+=` so deposits accumulate correctly instead of silently overwriting - V-TSI-02 (HIGH): Add caller-is-contract check via extcodesize to prevent EOAs from spoofing tokenReceived deposits - V-TSI-03 (MEDIUM): Reject zero-value deposits that could erase introspection records or waste gas - V-TSI-04 (LOW): Add ERC223DepositRecorded event for off-chain monitoring and auditability - V-TSI-05 (INFO): Replace magic number 0x8943ec02 with named constant _ERC223_RECEIVED with documentation All fixes verified to compile cleanly with solc 0.7.6. Co-authored-by: Cursor <cursoragent@cursor.com>
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.
Security Audit Report:
TokenStandardIntrospection.solSummary
Comprehensive security audit of
contracts/dex-core/TokenStandardIntrospection.solidentifying 5 vulnerabilities (2 HIGH, 1 MEDIUM, 1 LOW, 1 INFORMATIONAL) with fixes applied and verified to compile cleanly with solc 0.7.6.Contract Purpose
TokenStandardIntrospectionis a utility contract used by the Dex223 Factory to determine whether a given token address supports the ERC-223 standard. It implements thetokenReceived(address,uint256,bytes)hook: when an ERC-223 token is transferred to this contract, the token contract callstokenReceived, and the contract records the deposit. A subsequent call todepositedAmount(_token)reveals whether the transfer was processed (i.e., the token supports ERC-223).Vulnerabilities Found & Fixes Applied
V-TSI-01 — Deposit Overwrite Instead of Accumulation (HIGH)
Location:
TokenStandardIntrospection.sol:9Description: The original code uses assignment (
=) instead of addition (+=):If the same ERC-223 token sends multiple transfers to this contract, each new deposit completely overwrites the previous recorded balance. This causes the introspection data to misrepresent the actual cumulative deposits. While this contract is primarily used as a one-shot probe, using
=is semantically incorrect and can cause silent data loss if the contract is re-used or if multiple probes occur.Impact: Data integrity — previously recorded deposit amounts are silently erased by subsequent transfers from the same token.
Fix: Changed
=to+=so deposits accumulate correctly:V-TSI-02 — No Access Control on
tokenReceived— Spoofable Deposits (HIGH)Location:
TokenStandardIntrospection.sol:7-11Description: The
tokenReceivedfunction has no access control. Anyone can call it directly:This sets
erc223Deposits[caller_address]to an arbitrary value, makingdepositedAmount()return fraudulent data. An attacker could make any arbitrary address appear to be an ERC-223 token that deposited funds.In the ERC-223 standard,
tokenReceivedis called by the token contract itself duringtransfer(), somsg.sendershould always be a contract. There is no on-chain way to verify thatmsg.senderis truly an ERC-223 token without an external registry, but we can at minimum verify the caller is a contract (not an EOA).Impact: Any EOA can forge deposit records, corrupting the introspection data that the Factory relies on.
Fix: Added an
extcodesizecheck to ensure the caller is a contract:Residual risk: A malicious contract could still call
tokenReceivedwithout an actual ERC-223 transfer. This is acceptable because the contract's purpose is to probe token standard support, not to hold funds. The extcodesize check eliminates the much more likely EOA spoofing vector.V-TSI-03 — No Zero-Value Check Allows Deposit Record Erasure (MEDIUM)
Location:
TokenStandardIntrospection.sol:9Description: The original code allows
_value == 0to be recorded. Combined with vulnerability V-TSI-01 (the=assignment), a zero-value call would overwrite a real deposit with 0, effectively erasing the introspection record. Even with+=, a zero-value transfer is meaningless and wastes gas.Impact: Deposit records could be erased (with the
=bug), or gas wasted (with+=).Fix: Added zero-value rejection:
V-TSI-04 — Missing Events for Off-Chain Monitoring (LOW)
Location: Entire contract
Description: The original contract emits no events, making it impossible for off-chain indexers, monitoring dashboards, or security systems to track deposit activity. Events are critical for transparency and auditability in DeFi protocols.
Impact: No off-chain visibility into deposit activity on this contract.
Fix: Added
ERC223DepositRecordedevent emitted on each successful deposit:V-TSI-05 — Magic Number for Return Value Not Documented (INFORMATIONAL)
Location:
TokenStandardIntrospection.sol:10Description: The return value
0x8943ec02is used as a magic number without any documentation. This is actuallybytes4(keccak256("tokenReceived(address,uint256,bytes)")), the standard ERC-223 return selector. Without documentation, future developers may not understand its purpose or may accidentally change it.Fix: Replaced with a named constant:
Compilation Verification
_dataparameter (required by ERC-223 interface signature, cannot be removed)hardhat compilefailure (Revenue_old.sol and RevenueV1.sol using^0.8.13without a matching compiler config) is not related to these changesInterface Compatibility
The
ITokenStandardIntrospectioninterface (contracts/interfaces/ITokenStandardIntrospection.sol) remains fully compatible — no changes needed. Events and internal constants don't appear in interfaces.Test Plan
TokenStandardIntrospectionon a local Hardhat networktokenReceivedfrom an EOA reverts with"TSI: caller must be a contract"(V-TSI-02 fix)tokenReceivedwith_value == 0from a contract reverts with"TSI: zero value"(V-TSI-03 fix)TokenStandardIntrospection; verifydepositedAmountreturns the correct cumulative amount after multiple transfers (V-TSI-01 fix)ERC223DepositRecordedevent is emitted with correcttoken,from, andvaluefields (V-TSI-04 fix)tokenReceivedmatches0x8943ec02(V-TSI-05 — named constant)Dex223Factorycan still useITokenStandardIntrospectioninterface without any ABI mismatch