https://sherlock-files.ams3.digitaloceanspaces.com/profile_images/c0c5d8ea-f296-487a-a384-02fb5ad459bb.jpg

pkqs90

Security Researcher

gao()

Contact Me

High

1

Solo

61

Total

Medium

5

Solo

150

Total

$343.04K

Total Earnings

#25 All Time

31x

Payouts

gold

10x

1st Places

silver

5x

2nd Places

bronze

1x

3rd Places

All

Sherlock

Blackthorn

Code4rena

Cantina

May '25

Aave V3.4 - May 27th

Aave V3.4 - May 27th

Collaborative Audit • Blackthorn • pkqs90

Beraborrow Periphery Security Review

Beraborrow Periphery Security Review

Collaborative Audit • Sherlock • pkqs90

Apr '25

Beraborrow - Vault Update

Beraborrow - Vault Update

Collaborative Audit • Sherlock • pkqs90

Axion Update

Axion Update

Collaborative Audit • Sherlock • pkqs90

Mar '25

WrappedM token V2

WrappedM token V2

Collaborative Audit • Blackthorn • pkqs90

Jan '25

Peapods

Peapods

55,633.71 USDC • 29 total findings • Sherlock • pkqs90

gold

high

AutoCompoundingPodLp `_pairedLpTokenToPodLp()` does not correctly handle leftover pTKNs.

high

AutoCompoundingPodLp `_getSwapAmt()` does not return correct value for pairedLpTKN -> pTKN swaps.

high

spTKNMinimalOracle `_calculateSpTknPerBase()` does not calculate correct price for podded or fraxlend pair pairedLpTKNs.

high

LeverageManager remove leverage will lead to stuck tokens if slippage `_podSwapAmtOutMin` is set.

high

Potential vault initial deposit attack for AutoCompoundingPodLP and FraxlendPair

medium

FraxlendPair user liquidation may be frontrun, leading to loss of funds.

medium

LendingAssetVault incorrectly updates vaultUtilization if CBR for a single FraxlendPair decreases.

medium

TokenRewards.sol does not handle paused reward tokens, leading to loss of funds for users.

medium

FraxlendPair `minCollateralRequiredOnDirtyLiquidation` is never set, which allows avoidance of bad debt.

medium

FraxlendPair external `addInterest()` update logic is flawed, leading to inaccurate interest for LVA.

medium

LendingAssetVault should also call `_updateInterestAndMdInAllVaults()` in multiple functions.

medium

Pod's fee swap constraint allows users to snipe fees.

medium

pairedLpTKN as pTKN with non-zero transferTax is not supported in in multiple contracts.

medium

AutoCompoundingPodLp may double collect protocolFee for pairedLpTKN.

medium

AutoCompoundingPodLp does not work for advanced self-lending pods with podded fTKN as pairedLpTKN.

medium

AutoCompoundingPodLp `_swapV2()` may lead to leftover tokens in multihops.

medium

spTKNMinimalOracle calculates debondFee twice, leading to inaccurate oracle price.

medium

spTKNMinimalOracle uses DIA oracle which only supports /USD pairs, which incorrectly assumes all stablecoins are priced at 1 USD.

medium

spTKNMinimalOracle `_calculateSpTknPerBase()` does not return 0, which breaks the feature of having a fallback oracle.

medium

spTKNMinimalOracle does not support advanced self-lending pods, where pairedLpTKN is a podded fraxlend token.

medium

AutoCompoundingPodLP does not use correct oracle price as slippage for pairedLpTKn -> pTKN swap.

medium

Oracle circuit breaker check (minAnswer, maxAnswer) is incorrect.

medium

LeverageManager removeLeverage feature will often fail due to cached addInterest mechanism for FraxlendPair.

medium

LeverageManager closeFee is only collected for pTKN, which can be easily bypassed.

medium

LeverageManager remove leverage may fail for self-lending pods due to not enough tokens for repaying flashloan.

medium

LeverageManager removeLeverage does not support advanced self-lending pods with podded fTKN as pairedLpTKN.

medium

No usable DexAdapter on Berachain.

medium

Zapper `_swapV3Single()` has multiple integration issues with V3 swap.

medium

VotingPool.sol Uniswap V2 pricing formula for spTKN is incorrect

Majora

Majora

Collaborative Audit • Sherlock • pkqs90

Dec '24

Beraborrow Boyco

Beraborrow Boyco

Collaborative Audit • Sherlock • pkqs90

bima-money

bima-money

42,302.07 USDC • 15 total findings • Cantina • pkqs90

silver

high

Finding not yet public.

high

Finding not yet public.

high

Finding not yet public.

high

Finding not yet public.

high

Finding not yet public.

high

Finding not yet public.

high

Finding not yet public.

medium

Finding not yet public.

medium

Finding not yet public.

medium

Finding not yet public.

medium

Finding not yet public.

medium

Finding not yet public.

medium

Finding not yet public.

medium

Finding not yet public.

medium

Finding not yet public.

Nov '24

sorella-angstrom

sorella-angstrom

9,640.1 USDC • 1 total finding • Cantina • pkqs90

bronze

medium

Finding not yet public.

Oct '24

Ethos Network Social Contracts

Ethos Network Social Contracts

14,805.85 USDC • 2 total findings • Sherlock • pkqs90

silver

medium

Address is still marked as compromised when registered back by `registerAddress`.

medium

Corruptible Upgradability Pattern

LoopFi

LoopFi

11,339.25 USDC • 30 total findings • Code4rena • pkqs90

gold

high

`decreaseLever` uses incorrect position address when withdrawing

high

AuraVault inherits AccessControl BUT does not call the _setupRole() function in it's constructor to set the initial roles, this leads to a complete DOS of the important claim function rendering the contract unable to claim rewards

high

Liquidation doesn't account for penalty when calculating collateral to give, allowing users to profit by borrowing and self-liquidating

high

`Flashlender.sol#flashLoan()` should use `mintProfit()` to mint fees. The current implemetation may lead to locked up WETH in PoolV3.

high

`CDPVault.sol#liquidatePositionBadDebt()` should not set profit = 0 when calling `pool.repayCreditAccount()`.

high

It is nearly impossble for Liquidators to use `liquidatePosition()` to fully pay off a non bad-debt position.

high

`CDPVault.sol#liquidatePositionBadDebt()` does correctly handle profit and loss

medium

bug in `claim` allows users who are disqualified to claim their previously earned emissions

medium

Incorrect address is used as `spender` for ERC20 permit signature verification

medium

The debt in EligibilityDataProvider::requiredUsdValue() needs to be converted into USD; otherwise, it is not a correct value comparison.

medium

Because of the Asset:Share 1:1 Conversion, if Vault Incur a Loss, the Last User to Withdraw Will Take The Entire Loss

medium

PositionAction.decreaseLever() fails to consider the loan fee in Flashlender when calculating loanAmount, as a result, the functionanlity will not work when protocolFee != 0.

medium

Incorrect calculation of `newCumulativeIndex` in function `calcDecrease`

medium

WhenNotPaused modifier in the CDPVault can be bypassed by users

medium

DOS attack to SwapAction.transferAndSwap() when using an ERC20 permit transferFrom.

medium

Malicious actor can abuse the minimum shares check in `StakingLPEth` and cause DoS or locked funds for the last user that withdraws

medium

`PendleLPOracle::_fetchAndValidate` uses Chainlink's deprecated `answeredInRound`

medium

`PositionAction4626::_onDecreaseLever` wrongly updates `tokenOut` forcing user's funds to be stuck in the position action contract

medium

`PositionAction4626::increaseLever` will always revert

medium

PositionAction20._onWithdraw and PositionPendle20._onWithdraw also returns token amount in wrong scale

medium

Wrong repayment amount used in `PositionAction::_repay`, forcing users to unexpectedly lose funds

medium

`SwapAction.sol#balancerSwap` does not support native ETH as input token.

medium

ChefIncentivesController caches endRewardTime, which is not required, and may cause issues during reward update.

medium

`PositionAction4626.sol#_onWithdraw` should withdraw from `position` CDPVault position instead of `address(this)`.

medium

`PositionAction.sol#_deposit` incorrectly checks `auxSwap.assetIn` should be equal to `collateralParams.targetToken`.

medium

`PositionAction.sol#onCreditFlashLoan` may have leftover tokens after conducting `leverParams.auxSwap`.

medium

`PositionActionPendle.sol#_onWithdraw` does not have slippage parameter minOut set.

medium

`PositionAction4626.sol#_onWithdraw` should withdraw from position CDPVault position instead of `address(this)`.

medium

Invalid handling of flash loan fees in `PositionAction::onCreditFlashLoan`, forcing it to always revert

medium

`PositionAction.sol#onCreditFlashLoan` may end up with stuck funds for EXACT_IN primary swaps.

panoptic-core

panoptic-core

2,000 USDC • Cantina • pkqs90

silver
AXION

AXION

12,942.03 USDC • 6 total findings • Sherlock • pkqs90

gold

high

V2AMO is not compatible with Velodrome/Aerodrome.

high

V3AMO integration with V3 does not collect LP fees when burning liquidity.

high

Liquidity is incorrectly calculated during `addLiquidity()` for V3AMO, causing DoS.

high

Liquidity is incorrectly calculated during `unfarmBuyBurn()` for V3AMO, causing DoS.

medium

V3AMO is not compatible with Velodrome/Aerodrome CLPools

medium

Codebase is not compatible with ERC1504.

stakeup-bloomv2

stakeup-bloomv2

2,798.44 USDC • 10 total findings • Cantina • pkqs90

#7

high

Finding not yet public.

high

Finding not yet public.

high

Finding not yet public.

high

Finding not yet public.

high

Finding not yet public.

medium

Finding not yet public.

medium

Finding not yet public.

medium

Finding not yet public.

medium

Finding not yet public.

medium

Finding not yet public.

Sep '24

uniswap-v4

uniswap-v4

10,000 USDC • Cantina • pkqs90

#11

Aug '24

zetachain-protocol

zetachain-protocol

315.42 USDC • 3 total findings • Cantina • pkqs90

#39

high

Finding not yet public.

medium

Finding not yet public.

medium

Finding not yet public.

Midas - Instant Minter/Redeemer

Midas - Instant Minter/Redeemer

16,740.68 USDC • 6 total findings • Sherlock • pkqs90

gold

medium

RedemptionVaultWIthBUIDL does not redeem full balance if BUIDL balance is less than 250k post transaction.

medium

Standard redemption in `RedemptionVault` does not update token allowance.

medium

Corruptible Upgradability Pattern

medium

MBasisRedemptionVaultWithSwapper does not update mBasis daily limit or allowance when conducting mBasis->mTBill swap.

medium

Discrepancy between spec and code: Vault admin cannot update `tokensReceiver`.

medium

`RedemptionVaultWIthBUIDL.sol#redeemInstant` will always DoS due to incorrect contract call.

Jul '24

LoopFi

LoopFi

17,219.34 USDC • 30 total findings • Code4rena • pkqs90

gold

high

`decreaseLever` uses incorrect position address when withdrawing

high

AuraVault inherits AccessControl BUT does not call the _setupRole() function in it's constructor to set the initial roles, this leads to a complete DOS of the important claim function rendering the contract unable to claim rewards

high

Liquidation doesn't account for penalty when calculating collateral to give, allowing users to profit by borrowing and self-liquidating

high

`Flashlender.sol#flashLoan()` should use `mintProfit()` to mint fees. The current implemetation may lead to locked up WETH in PoolV3.

high

`CDPVault.sol#liquidatePositionBadDebt()` should not set profit = 0 when calling `pool.repayCreditAccount()`.

high

It is nearly impossble for Liquidators to use `liquidatePosition()` to fully pay off a non bad-debt position.

high

`CDPVault.sol#liquidatePositionBadDebt()` does correctly handle profit and loss

medium

bug in `claim` allows users who are disqualified to claim their previously earned emissions

medium

Incorrect address is used as `spender` for ERC20 permit signature verification

medium

The debt in EligibilityDataProvider::requiredUsdValue() needs to be converted into USD; otherwise, it is not a correct value comparison.

medium

Because of the Asset:Share 1:1 Conversion, if Vault Incur a Loss, the Last User to Withdraw Will Take The Entire Loss

medium

PositionAction.decreaseLever() fails to consider the loan fee in Flashlender when calculating loanAmount, as a result, the functionanlity will not work when protocolFee != 0.

medium

Incorrect calculation of `newCumulativeIndex` in function `calcDecrease`

medium

WhenNotPaused modifier in the CDPVault can be bypassed by users

medium

DOS attack to SwapAction.transferAndSwap() when using an ERC20 permit transferFrom.

medium

Malicious actor can abuse the minimum shares check in `StakingLPEth` and cause DoS or locked funds for the last user that withdraws

medium

`PendleLPOracle::_fetchAndValidate` uses Chainlink's deprecated `answeredInRound`

medium

`PositionAction4626::_onDecreaseLever` wrongly updates `tokenOut` forcing user's funds to be stuck in the position action contract

medium

`PositionAction4626::increaseLever` will always revert

medium

PositionAction20._onWithdraw and PositionPendle20._onWithdraw also returns token amount in wrong scale

medium

Wrong repayment amount used in `PositionAction::_repay`, forcing users to unexpectedly lose funds

medium

`SwapAction.sol#balancerSwap` does not support native ETH as input token.

medium

ChefIncentivesController caches endRewardTime, which is not required, and may cause issues during reward update.

medium

`PositionAction4626.sol#_onWithdraw` should withdraw from `position` CDPVault position instead of `address(this)`.

medium

`PositionAction.sol#_deposit` incorrectly checks `auxSwap.assetIn` should be equal to `collateralParams.targetToken`.

medium

`PositionAction.sol#onCreditFlashLoan` may have leftover tokens after conducting `leverParams.auxSwap`.

medium

`PositionActionPendle.sol#_onWithdraw` does not have slippage parameter minOut set.

medium

`PositionAction4626.sol#_onWithdraw` should withdraw from position CDPVault position instead of `address(this)`.

medium

Invalid handling of flash loan fees in `PositionAction::onCreditFlashLoan`, forcing it to always revert

medium

`PositionAction.sol#onCreditFlashLoan` may end up with stuck funds for EXACT_IN primary swaps.

Super Boring

Super Boring

18,915.20 USDC • Sherlock • pkqs90

gold

Findings not publicly available for private contests.

Deepr

Deepr

20,601.18 USDC • Sherlock • pkqs90

silver

Findings not publicly available for private contests.

Jun '24

Size

Size

8,385.15 USDC • 8 total findings • Code4rena • pkqs90

#6

high

Users won't liquidate positions because the logic used to calculate the liquidator's profit is incorrect

high

When `sellCreditMarket()` is called to sell credit for a specific cash amount, the protocol might receive a lower swapping fee than expected.

medium

Fragmentation fee is not taken if user compensates with newly created position

medium

Borrower is not able to compensate his lenders if he is underwater

medium

Users may incur an unexpected fragmentation fee in the `compensate()` call

medium

Users can not to buy/sell minimum credit allowed due to exactAmountIn condition

medium

Multicall does not work as intended

medium

LiquidateWithReplacement does not charge swap fees on the borrower

May '24

Midas

Midas

5,558.62 USDC • 2 total findings • Sherlock • pkqs90

gold

medium

Corruptible Upgradability Pattern

medium

DEPOSIT_VAULT_ADMIN_ROLE/REDEMPTION_VAULT_ADMIN_ROLE have larger permission than expected: they shouldn't be able to pause vaults

Predy

Predy

43,311.87 USDC • 6 total findings • Code4rena • pkqs90

gold

high

Liquidators can bypass remaining negative margin check and leave the loss to the protocol

high

Liquidation incorrectly tries to transfer token from Market instead of liquidator if remainingMargin is negative

medium

Reallocation incorrectly sends the exceed quoteTokens to Market contract instead of reallocator

medium

Vaults can become immune from liquidation by setting `vault.recipient` to a blacklisted quote token address

medium

Possible DoS When calling `GammaTradeMarket::_removePosition` will cause user position to not be able to get liquidated

medium

Chainlink's `latestRoundData` might return stale or incorrect results

Gamma - Locked Staking Contract

Gamma - Locked Staking Contract

9,313.29 USDC • 2 total findings • Sherlock • pkqs90

gold

medium

Integer overflow when calculating rewards

medium

No slippage check for penalty payment for `earlyExitById()` function

Apr '24

NOYA

NOYA

2,893.72 USDC + NOYA stars • 27 total findings • Code4rena • pkqs90

#6

high

BalancerConnector has incorrect implementation of totalSupply, positionTVL and total TVL will be invalid

high

`Registry.sol#updateHoldingPosition` remove position logic is incorrect: should use `ownerConnector` instead of `calculatorConnector` when calculating holdingPositionId.

high

`SNXConnector.sol` TVL calculation is incorrect.

high

Incomplete TVL Calculation in `AerodromeConnector::_getPositionTVL` Function.

high

`executeWithdraw` may be blocked if any of the users are blacklisted from the `baseToken`

high

Numerous errors when calculating the TVL for the MorphoBlue connector

high

It is possible to open insolvent position is Silo connector, due to missing check in borrow function

medium

`veMav` token in `MaverickConnector` does NOT have an existing oracle, so staking Mav would always lead to DoS for TVL calculation

medium

`AccountingManager#totalWithdrawnAmount` should reflect tokens actually transferred to users, instead of expected transfers

medium

`CurveConnector.sol#depositIntoConvexBooster` does not keep track of TVL if `stake == false`

medium

`FraxConnector.sol#repay` approved amount of tokens does NOT account for latest interest, which may cause DoS while repaying

medium

`PrismaConnector.sol` should also check health factor in `openTrove()` function

medium

`_getPositionTVL()` of The StargateConnector doesn't accoount for the total value locked.

medium

The `TVLHelper.sol#getTVL` function is DOSed by the `under collateralized connector`, and as a result, many parts of the protocol may be DOS.

medium

The modifier `onlyExistingRoute` works incorrectly

medium

Attacker can increase the length of `withdrawQueue` by withdrawing 0 amount of tokens frequently

medium

Incorrect Return Value in `CompoundConnector.getBorrowBalanceInBase()` Affecting TVL Calculation

medium

In the BalancerConnector, unclaimed rewards are not included in the calculation of the connectors TVL

medium

Missing calls to `_updateTokenInRegistry` leads to incorrect state of tokens in registry

medium

Incorrect modifier condition

medium

Extra rewards are not updated in curve connector when harvestConvexRewards is called

medium

In the `Gearboxv3` connector the health factor of the account is never considered

medium

In the AerodromeConnector, unclaimed rewards are not included in the calculation of the connectors TVL

medium

Due to missing health factor and hardcoded balance checks on Dolomite, a borrow position can be opened by withdrawing more than the supplied balance leading to possible unwanted liquidations

medium

Lack of functionality for `claimFees` calls to the Aerodrome Pool causes the connector to lose its deserved fees

medium

`depositQueue.queue` in `AccountingManager` can be flooded causing a DoS

medium

No function to claim the reward in `PancakeswapConnector`.

Teller Finance

Teller Finance

1,414.70 USDC • 12 total findings • Sherlock • pkqs90

#4

high

Lender of the loan cannot perform `lenderCloseLoan()`/`setRepaymentListenerForBid()` after calling `claimLoanNFT()`

high

`_getCollateralTokensAmountEquivalentToPrincipalTokens` uses incorrect min/max for token oracle prices, allowing attackers to use sandwich attacks to borrow a loan with very little collateral.

high

`STANDARD_EXPANSION_FACTOR` is not needed

high

In `LenderCommitmentGroup_Smart.sol#burnSharesToWithdrawEarnings()`, shares are burned before `principalTokenValueToWithdraw` is calculated, causing users to withdraw more tokens than expected.

high

`LenderCommitmentGroup_Smart.sol#liquidateDefaultedLoanWithIncentive` does NOT send collateral to caller, but to the `LenderCommitmentGroup_Smart` pool

high

Protocol fails to work with ERC20s that does NOT revert on failure during transfer.

medium

Borrowers may receive less tokens than they expect due to fee change after submitting a bid.

medium

`LenderCommitmentGroup_Smart.sol` cannot deploy pools with non-string symbol() ERC20s.

medium

`LenderCommitmentGroup_Smart.sol#_getPriceFromSqrtX96` may overflow

medium

`LenderCommitmentGroup_Smart.sol#sharesExchangeRateInverse()` may divide by zero

medium

`FlashRolloverLoan_G5#rolloverLoanWithFlash` does not support fee-on-transfer tokens

medium

Users can bypass auction mechanism for `LenderCommitmentGroup_Smart` liquidation mechanism for loans that are close to end of loan

Panoptic

Panoptic

4,146.86 USDC • 2 total findings • Code4rena • pkqs90

#5

high

`SettleLongPremium` is incorrectly implemented: premium should be deducted instead of added

medium

`_validatePositionList()` does not check for duplicate tokenIds, allowing attackers to bypass solvency checks

Mar '24

Ondo Finance

Ondo Finance

8.28 USDC • Code4rena • pkqs90

#17

vVv Vesting & Staking

vVv Vesting & Staking

1,315.78 USDC • Sherlock • pkqs90

silver
M^0

M^0

31,172.75 USDC • 3 total findings • Sherlock • pkqs90

gold

medium

Malicious minters can repeatedly penalize their undercollateralized accounts in a short peroid of time, which can result in disfunctioning of critical protocol functions, such as `mintM`.

medium

Validator threshold can be bypassed: a single compromised validator can update minter's state to historical state

medium

No incentive for user to call `stopEarning` for M Tokens

Feb '24

Althea Liquid Infrastructure

Althea Liquid Infrastructure

106.29 USDC • 2 total findings • Code4rena • pkqs90

#22

medium

`LiquidInfrastructureERC20.sol` disapproved holders keep part of the supply, diluting approved holders revenue.

medium

Distribution can be bricked, and double claims by a few holders are possible when owner calls `LiquidInfrastructureERC20::setDistributableERC20s`

AI Arena

AI Arena

4.37 USDC • 5 total findings • Code4rena • pkqs90

#138

high

A locked fighter can be transferred; leads to game server unable to commit transactions, and unstoppable fighters

high

Players have complete freedom to customize the fighter NFT when calling `redeemMintPass` and can redeem fighters of types Dendroid and with rare attributes

high

Fighters cannot be minted after the initial generation due to uninitialized `numElements` mapping

high

Non-transferable `GameItems` can be transferred with `GameItems::safeBatchTransferFrom(...)`

medium

Fighter created by mintFromMergingPool can have arbitrary weight and element

Jan '24

Arcadia

Arcadia

36.24 USDC • 1 total finding • Sherlock • pkqs90

#8

medium

Rewards for StakedStargateAM is calculated incorrectly

Decent

Decent

23.07 USDC • 1 total finding • Code4rena • pkqs90

#50

medium

Missing access control on UTB:receiveFromBridge allows UTB swaps to be executed without spending bridge fees while bypassing fee/swap instruction signature verification

Salty.IO

Salty.IO

79.35 USDC • 4 total findings • Code4rena • pkqs90

#76

high

When borrowers repay USDS, it is sent to the wrong address, allowing anyone to burn Protocol Owned Liquidity and build bad debt for USDS

high

User can evade `liquidation` by depositing the minimum of tokens and gain time to not be liquidated

medium

Unwhitelisting does not clear _arbitrageProfits, so re-whitelisting may result in an unfair distribution of liquidity rewards.

medium

Impossible to change managed wallets with `proposeWallets` after first rejection

Curves

Curves

5.12 USDC • 4 total findings • Code4rena • pkqs90

#100

high

Unrestricted claiming of fees due to missing balance updates in `FeeSplitter`

medium

onBalanceChange causes previously unclaimed rewards to be cleared

medium

Curves::_buyCurvesToken(), Excess of Eth received is not refunded back to the user.

medium

If a user sets their curve token symbol as the default one plus the next token counter instance it will render the whole default naming functionality obsolete

reNFT

reNFT

14.38 USDC • Code4rena • pkqs90

#58

Nov '23

Majora

Majora

Collaborative Audit • Sherlock • pkqs90