Skip to content
$1,000,000 in security audit grants are live now, Apply here →

Security review · March 2025

KYC Whitelist

for Bracket

Bracket engaged Guardian to review the security of their kyc functionality. From the 17th of April to the 18th of April, a team of 3 auditors reviewed the source code in scope.

Published
Review window
April 17 to 18, 2025
Language
Solidity
Chains
Ethereum
Sector
Governance
  • 0 Critical
  • 1 High
  • 2 Medium
  • 1 Low
  • 6 Informational

8 resolved · 2 acknowledged

Scope

Overview

Bracket engaged Guardian to review the security of their kyc functionality. From the 17th of April to the 18th of April, a team of 3 auditors reviewed the source code in scope.

Findings 10

  1. H-01 High Incorrect stethAmount Used Logical Error Resolved
    Location
    BrktETHRouter.sol

    Description

    In the _lidoEthToBrktETH function the return value from the submit function is used as the stEth amount gained from the submit call.

    However the return value represents the amount of stEth shares, not the amount of stEth which were gained from the submit call.

    As a result a significant portion of stEth will be left in the router contract and the user will not receive bracketEth for this amount.

    Recommendation

    Use the difference between the stEth balance before and after calling the submit function to wrap in the wstEth contract.

    Resolution

    Bracket Team: The issue was resolved in commit c23fed5.

  2. M-01 Medium KycWhitelist Cannot Be Deployed Logical Error Resolved
    Location
    KYCWhitelist.sol

    Description

    The KYCWhitelist contract cannot be successfully deployed because the initializing functions used in the constructor use an onlyInitializing modifier.

    Recommendation

    Refactor the KYCWhitelist contract so that the constructor is the initializer or make a separate initializer function.

    Resolution

    Bracket Team: The issue was resolved in commit 7b70cb2.

  3. M-02 Medium Incorrect STETH Address Logical Error Resolved
    Location
    Config.sol

    Description

    The STETH address in the Config contract is incorrect as it points to the STETH implementation contract (0x17144556fd3424EDC8Fc8A4C940B2D04936d17eb) rather than the correct proxy contract (0xae7ab96520de3a18e5e111b5eaab095312d7fe84).

    Recommendation

    Update the STETH address to be the correct proxy address.

    Resolution

    Bracket Team: The issue was resolved in commit ca93c8a.

  4. L-01 Low Missing Whitelisted From Check Validation Resolved
    Location
    RebasingToken.sol: 81

    Description

    In the _update function there is no validation that the from address is whitelisted on transfer. This allows unwhitelisted addresses to transfer to whitelisted addresses which may be unexpected.

    Recommendation

    Consider adding validation that the from address is also whitelisted in the _update function.

    Resolution

    Bracket Team: The issue was resolved in commit 70793e1.

  5. I-01 Informational Transfer Optimization Documentation Resolved
    Location
    RebasingToken.sol: 78

    Description

    The _update function performs _clearDeposit in all cases, even when the _update invocation is for a mint or burn call.

    There are no significant issues from this as the _clearDeposit call will always early return for minting and burning updates.

    However to avoid any hidden introduction of issues in the future and to optimize gas expenditure, this unexpected execution should be avoided.

    Recommendation

    Consider only invoking the _clearDeposit function when the from address and to address are both nonzero, indicating that the update action is a legitimate transfer.

    Resolution

    Bracket Team: The issue was resolved in commit 6717a3d.

  6. I-02 Informational Unnecessary Payable Modifier Best Practices Resolved
    Location
    BrktEthRouter.sol: 47

    Description

    The wethToBrktETH function includes a payable modifier yet does not handle msg.value.

    Recommendation

    Remove the payable modifier from the wethToBrktETH function.

    Resolution

    Bracket Team: The issue was resolved in commit 566e943.

  7. I-03 Informational Misleading ETHToBrktETH Event Data Events Resolved
    Location
    BrktEthRouter.sol: 42, 53

    Description

    The ETHToBrktETH event emission in the ethToBrktETH and wethToBrktETH functions emits the minimum acceptable brktEth amount rather than the actual minted brktEth amount from the action. This may be misleading for consumers of the ETHToBrktETH event.

    Recommendation

    Consider if the actual minted brktEth amount should be emitted in the ETHToBrktETH event.

    Resolution

    Bracket Team: The issue was resolved in commit b0f4119.

  8. I-04 Informational Missing VanityNavUpdated Event Events Acknowledged
    Location
    BracketVault.sol

    Description

    The updateNav function updates the vanityNav but does not emit a VanityNavUpdated event. This may mislead indexers and consumers of the VanityNavUpdated event if they are not aware of this behavior.

    Recommendation

    Consider if this behavior is intended, if not, consider emitting the VanityNavUpdated event in the updateNav function.

    Resolution

    Bracket Team: Acknowledged.

  9. I-05 Informational Unnecessary Paused Check Gas Optimization Resolved
    Location
    BrktEthRouter.sol: 75

    Description

    In the lidoLimit function the isStakingPaused function is queried on the steth contract. If staking is paused the result of the limit is 0.

    However this logic is already included in the lido underlying getCurrentStakeLimit function and therefore is unnecessary in the lidoLimit function.

    Recommendation

    Consider removing the unnecessary isStakingPaused logic in the lidoLimit function.

    Resolution

    Bracket Team: The issue was resolved in commit b677547.

  10. I-06 Informational Hardcoded RocketDepositPool Best Practices Acknowledged
    Location
    BrktEthRouter.sol

    Description

    The RocketDepositPool contract is hardcoded as a constant in the BrktEthRouter contract. However the latest RocketDepositPool is allowed to change in the RocketStorage contract.

    Recommendation

    Be aware of this possibility and consider adding a setter function for the RocketDepositPool contract in case it were to be updated by Rocket Pool.

    Resolution

    Bracket Team: Acknowledged.

More from Bracket

  1. Contract Updates

    37 findings2 critical · 8 high 37 findings: 2 critical, 8 high, 9 medium, 14 low, 4 informational
  2. LST Vault, Round 2

    26 findings2 high 26 findings: 2 high, 1 medium, 23 low
  3. BracketFi, Round 1

    34 findings3 critical · 2 high 34 findings: 3 critical, 2 high, 9 medium, 20 low

Put your code through the same review.

This review started with a conversation about scope. Tell us what you are building and we will plan yours with you.

Get a quote