Skip to content

Add CPI Guard check to WithdrawExcessLamports for consistency #1033

@Tgcohce

Description

@Tgcohce

process_withdraw_excess_lamports is the only owner-authorized operation on token accounts that does not enforce CPI Guard. All 7 others do:

Operation CPI Guard check Error
Transfer Yes CpiGuardTransferBlocked
Approve Yes CpiGuardApproveBlocked
SetAuthority Yes CpiGuardSetAuthorityBlocked
Burn Yes CpiGuardBurnBlocked
CloseAccount Yes CpiGuardCloseAccountBlocked
UnwrapLamports Yes CpiGuardTransferBlocked
WithdrawExcessLamports No

This means WithdrawExcessLamports can be called via CPI on a token account with CPI Guard enabled, while every other owner-authorized operation is blocked.

UnwrapLamports is the closest analogue (both extract SOL from a token account with owner authorization) and it has the check.

If this is intentional, it might be worth documenting. If not, the fix would be adding the standard check in the token-account branch of process_withdraw_excess_lamports, after validate_owner:

if let Ok(cpi_guard) = account.get_extension::<CpiGuard>() {
    if cpi_guard.lock_cpi.into() && in_cpi() {
        return Err(TokenError::CpiGuardTransferBlocked.into());
    }
}

The CPI Guard test suite (clients/rust-legacy/tests/cpi_guard.rs) covers all 7 other operations but not WithdrawExcessLamports.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions