Skip to content
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

Scrawny Cobalt Goldfish - Withdraw/Redeem functions can fail due to blocked USDT/USDC accounts #78

Open
sherlock-admin2 opened this issue Sep 24, 2024 · 0 comments

Comments

@sherlock-admin2
Copy link
Contributor

Scrawny Cobalt Goldfish

Medium

Withdraw/Redeem functions can fail due to blocked USDT/USDC accounts

Summary

Withdraw and redeem functions in smart contracts can fail if they involve transferring USDT, USDC, or other centralized stablecoins from blocked or blacklisted accounts. Both Tether (USDT) and USD Coin (USDC) are issued by centralized entities with the authority to freeze or blacklist addresses. When an account is blacklisted, any attempts to transfer these tokens from the blacklisted address will be blocked, causing the transaction to fail.

This issue can significantly impact decentralized finance (DeFi) protocols, which rely on seamless token transfers for operations like withdrawals and redemptions. If a user's address or the contract itself gets blacklisted, users may be unable to withdraw their funds, leading to a loss of trust and potentially severe financial consequences.

Vulnerability Detail

pub fn deposit(ctx: Context, amount: u128) -> Result<()> {
let token_owner_account = &ctx.accounts.token_owner_account;
let token_vault = &ctx.accounts.token_vault;
let woopool = &mut ctx.accounts.woopool;

let _balance_before = balance(woopool, token_vault)?;

require!(
    token_owner_account.amount as u128 >= amount,
    ErrorCode::NotEnoughBalance
);

woopool.add_reserve(amount)?;

transfer_from_owner_to_vault(
    &ctx.accounts.authority,
    token_owner_account,
    token_vault,
    &ctx.accounts.token_program,
    amount as u64,
)?;

emit!(DepositEvent {
    authority: ctx.accounts.authority.key(),
    token_mint: woopool.token_mint,
    deposit_amount: amount,
});

Ok(())

}
pub fn withdraw(ctx: Context, amount: u128) -> Result<()> {
let token_owner_account = &ctx.accounts.token_owner_account;
let token_vault = &ctx.accounts.token_vault;
let woopool = &mut ctx.accounts.woopool;

let _balance_before = balance(woopool, token_vault)?;

require!(
    woopool.reserve >= amount && token_vault.amount as u128 >= amount,
    ErrorCode::NotEnoughBalance
);

woopool.sub_reserve(amount)?;

transfer_from_vault_to_owner(
    woopool,
    token_vault,
    token_owner_account,
    &ctx.accounts.token_program,
    amount as u64,
)?;

emit!(WithdrawEvent {
    authority: ctx.accounts.authority.key(),
    token_mint: woopool.token_mint,
    withdraw_amount: amount,
});

Ok(())

}

Impact

Withdraw/Redeem functions can fail due to blocked USDT/USDC accounts

Code Snippet

https://github.com/sherlock-audit/2024-08-woofi-solana-deployment/blob/main/WOOFi_Solana/programs/woofi/src/instructions/admin/deposit_withdraw.rs#L38

Tool used

Manual Review

Recommendation

A potential way to fix this issue is to allow users to specify an alternative address for the transfer to go to. However, the contract must still validate that the withdrawal amount is correctly debited from the msg.sender's balance to prevent any unauthorized transfers. This ensures that users cannot steal other users' assets by specifying different addresses.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant