https://sherlock-files.ams3.digitaloceanspaces.com/twitter_images/43c98237-b564-4282-b297-aec7b0d4edd1.jpg

unforgiven

Security Researcher

Researcher

Contact Me

High

66

Total

Medium

3

Solo

115

Total

$219.83K

Total Earnings

#40 All Time

45x

Payouts

gold

4x

1st Places

silver

5x

2nd Places

bronze

7x

3rd Places

All

Sherlock

Code4rena

Oct '24

Velodrome Superchain

Velodrome Superchain

Collaborative Audit • Sherlock • unforgiven

Mar '24

Optimism Fault Proofs

Optimism Fault Proofs

2,000 USDC • Sherlock • unforgiven

#7

Jan '24

LooksRare YOLO

LooksRare YOLO

104.78 USDC • 2 total findings • Sherlock • unforgiven

#5

high

attacker can DOS or manipulate rounds deposits count by depositing 0 ETH with depositETHIntoMultipleRounds()

medium

attacker can DOS and LOCK users tokens because function depositETHIntoMultipleRounds() doesn't check MAXIMUM_NUMBER_OF_DEPOSITS_PER_ROUND

Truflation

Truflation

196.81 USDC • 2 total findings • Sherlock • unforgiven

#7

high

function claimable() in TrufVesting may return value bigger than maxClaimable

medium

function _extendLock() allows extending the expired lockups

Nov '23

Nouns Builder

Nouns Builder

1,907.01 USDC • 3 total findings • Sherlock • unforgiven

#4

high

auction settlements will revert because function `_computeTotalRewards()` calculates inconsistent totalReward and reward list

high

function _addFounders() in Token contract doesn't support more than 99 funder with ownershipPct and also it doesn't support less than 1% pct

medium

attacker can force pause the Auctions

Mar '23

Optimism Update

Optimism Update

2,636.90 USDC • 1 total finding • Sherlock • unforgiven

#7

medium

DOS and griefing the sequencer by bridging large data deposits from L1 to L2 with low gas

zkSync Era System Contracts contest

zkSync Era System Contracts contest

5,261.57 USDC • 1 total finding • Code4rena • unforgiven

#6

medium

deploying contracts with forceDeployOnAddress will break contracts when callConstructor is false

Feb '23

Surge

Surge

121.76 USDC • 2 total findings • Sherlock • unforgiven

#16

high

Attacker can manipulate loan token price per share in the Pool and users would lose funds due to division error

medium

fund loss because calculated Interest would be 0 in getCurrentState() due to division error

Hats

Hats

1,269.50 USDC • 5 total findings • Sherlock • unforgiven

#4

high

middle level admins can take control of the tree after unlinking it because function unlinkTopHatFromTree() doesn't reset the value of the linkedTreeRequests[]

medium

middle level admins can steal child trees because function unlinkTopHatFromTree() is callable by them

medium

function reconcileSignerCount() set higher value for safe's threshold which can cause safe's transaction execution to revert always

medium

attacker can perform malicious transactions in the safe because reentrancy is not implemented correctly in the checkTransaction() and checkAfterExecution() function in HSG

medium

Unbound recursive function call can use unlimited gas and break hats operation

Carapace

Carapace

172.75 USDC • 3 total findings • Sherlock • unforgiven

#25

high

unbound loops in the code which can cause high gas usage and break the protocol and fund would be locked

high

Protection sellers can bypass withdrawal delay mechanism and avoid losing funds when loans are defaulted by creating withdrawal request in each cycle

medium

function lockCapital() doesn't filter the expired protections first and code may lock more funds than required and expired defaulted protections may funded

OpenQ

OpenQ

6,346.33 USDC • 10 total findings • Sherlock • unforgiven

silver

high

attacker can cause claims of the atomicBounty and TieredPercentageBounty to revert if one of the whitelisted tokens revert when transferring 0 amount

high

attacker can cause calls to claim function of the all Bounty types (except Ongoing) to revert because code would try to transfer refunded NFT deposits

high

attacker can cause claim calls to bounty type TieredPercentageBounty to revert always by refunding his deposit after closeCompetition() get called

high

malicious winner in the TieredPercentageBounty can steal other winner funds by inflating contract token balance right before claiming and then refunding his deposit

high

Function refundDeposit() in BountyCore doesn't decrease deposit items and it can cause deposits to reach to the limit even so they are refunded

medium

Attacker can perform DOS on any bounty contract by over calling fundBountyToken() with different tokens

medium

Attacker can perform griefing and DOS by deposit and refunding NFTs into the bounty

medium

Wrong fund distribution when users refunds deposits between claims and deposits set as refunded while code refund them partially

medium

call to setPayoutSchedule() and setPayoutScheduleFixed() would revert when bounty's issuer try to resize winners to fewer tiers

medium

when issuer set new winner by calling setTierWinner() code should reset invoice and supporting documents for that tier

Jan '23

Optimism

Optimism

42,854.47 USDC • 4 total findings • Sherlock • unforgiven

bronze

medium

[High] Function PreCheckWithdrawals() assumes that all the messages in the LegacyMessagePasserAddr are from L2CrossDomainMessanger and attacker can break migration script by calling OVM_L2ToL1MessagePasser.passMessageToL1() before migration

medium

[High] Attacker can block other users L2 to L1 withdrawals in the OptimisimPortal and lock their funds by proving it to the wrong output index if sequencer send invalid L2 output root(future L2 blocks states) for that index

medium

[Medium] Challenger shouldn't be able to delete finalized L2 outputs

medium

[High] Function MigrateWithdrawal() may set gas limit so high for old withdrawals when migrating them by mistake and they can't be relayed in the L1 and users funds would be lost

Reserve contest

Reserve contest

11,816.64 USDC • 5 total findings • Code4rena • unforgiven

#4

medium

BackingManager: rTokens might not be redeemable when protocol is paused due to missing token allowance

medium

attacker can prevent vesting for a very long time

medium

attacker can steal RToken holders funds by performing reentrancy attack during redeem() function token transfers

medium

early user can call issue() and then melt() to increase basketsNeeded to supply ratio to its maximum value and then melt() won't work and contract contract features like issue() won't work

medium

attacker can make stakeRate to be 1 in the StRSR contract and users depositing tokens can lose funds because of the big rounding error

Astaria contest

Astaria contest

1,959.34 USDC • 9 total findings • Code4rena • unforgiven

#13

high

Function processEpoch() in PublicVault would revert when most of the users withdraws their funds because of the underflow for new yIntercept calculation

high

Attacker can take loan for Victim

high

Improper validations in Clearinghouse. possible to lock collateral NFT in contract.

high

Deadlock in valuts with underlying token with less then 18 decimals

medium

Function withdraw() and redeem() in ERC4626RouterBase would revert always because they have unnecessary allowance setting

medium

WithdrawProxy allows redeem() to be called before withdraw reserves are transferred in

medium

For a public vault, minimum deposit requirement that is enforced by `ERC4626Cloned.deposit` function can be bypassed by `ERC4626Cloned.mint` function or vice versa when share price does not equal one

medium

Users are unable to mint shares from a public vault using `AstariaRouter` contract when share price is bigger than one

medium

Lack of support for fee-on-transfer token

UXD Protocol

UXD Protocol

51.94 USDC • 1 total finding • Sherlock • unforgiven

#26

high

[High] attacker can drain or theft any user who gave spending allowance for PerpDepository contract by calling rebalanceLite()

Dec '22

Papr contest

Papr contest

2,603.35 USDC • 4 total findings • Code4rena • unforgiven

#7

high

Stealing fund by applying reentrancy attack on `removeCollateral`, `startLiquidationAuction`, and `purchaseLiquidationAuctionNFT`

medium

`PaprController` pays swap fee in `buyAndReduceDebt`, not user

medium

user fund loss because function purchaseLiquidationAuctionNFT() take extra liquidation penalty when user's last collateral is liquidated, (set wrong value for maxDebtCached when isLastCollateral is true)

medium

Disabled NFT collateral should not be used to mint debt

GoGoPool contest

GoGoPool contest

8,696.71 USDC • 13 total findings • Code4rena • unforgiven

gold

high

Inflation of ggAVAX share price by first depositor

high

Hijacking of node operators minipool causes loss of staked funds

high

node operator is getting slashed for full duration even though rewards are distributed based on a 14 day cycle

high

AVAX Assigned High Water is updated incorrectly

medium

Division by zero error can block RewardsPool#startRewardCycle if all multisig wallet are disabled.

medium

Users may not be able to redeem their shares due to underflow

medium

maxWithdraw() and maxRedeem() doesn't return correct value which can make other contracts fail while working with protocol

medium

wrong reward distribution between early and late depositors because of the late syncRewards() call in the cycle, syncReward() logic should be executed in each withdraw or deposits (without reverting)

medium

any duration can be passed by node operator

medium

Cancellation of minipool may skip MinipoolCancelMoratoriumSeconds checking if it was cancelled before

medium

Functions cancelMinipool() doesn't reset the value of the RewardsStartTime for user when user's minipoolcount is zero

medium

NodeOp funds may be trapped by a invalid state transition

medium

Coding logic of the contract upgrading renders upgrading contracts impractical

Caviar contest

Caviar contest

2,184.49 USDC • 4 total findings • Code4rena • unforgiven

bronze

high

Liquidity providers may lose funds when adding liquidity

high

First depositor can break minting of shares

medium

Rounding error in buyQuote might result in free tokens

medium

it's possible to swap NFT token ids without fee and also attacker can wrap unwrap all the NFT token balance of the Pair contract and steal their air drops for those token ids

Tigris Trade contest

Tigris Trade contest

5,519.19 USDC • 7 total findings • Code4rena • unforgiven

bronze

high

Malicious user can steal all assets in BondNFT

high

reentrancy attack during mint() function in Position contract which can lead to removing of the other user's limit orders or stealing contract funds because initId is set low value

medium

GovNFT: maxBridge has no effect

medium

one can become referral of hash 0x0 and because all users default referral hash is 0x0 so he would become all users referral by default and earn a lot of fees while users didn't approve it

medium

distribute() won't update epoch[tigAsset] when totalShares[tigAsset]==0 which can cause later created bond for this tigAsset to have wrong mint epoch

medium

`_handleDeposit` and `_handleWithdraw` do not account for tokens with decimals higher than 18

medium

Governance NFT holder, whose NFT was minted before `Trading._handleOpenFees` function is called, can lose deserved rewards after `Trading._handleOpenFees` function is called

prePO contest

prePO contest

1,803.53 USDC • 2 total findings • Code4rena • unforgiven

#5

high

griefing / blocking / delaying users to withdraw

medium

`PrePOMarket.setFinalLongPayout()` shouldn't be called twice.

Nov '22

ParaSpace contest

ParaSpace contest

7,846.74 USDC • 8 total findings • Code4rena • unforgiven

bronze

high

Interest rates are incorrect on Liquidation

high

Anyone can prevent themselves from being liquidated as long as they hold one of the supported NFTs

high

Data corruption in NFTFloorOracle; Denial of Service

medium

safeTransfer is not implemented correctly

medium

New BAKC Owner Can Steal ApeCoin

medium

NTokenMoonBirds Reserve Pool Cannot Receive Airdrops

medium

user collateral NFT open auctions would be sold as min price immediately next times user health factor gets below the liquidation threshold, protocol should check health factor and set auctionValidityTime value anytime an valid action happen to user accou

medium

Centralization risk: admin can with rug the project by removing asset and price manipulation on oracle.

Redacted Cartel contest

Redacted Cartel contest

5,985.19 USDC • 8 total findings • Code4rena • unforgiven

bronze

high

Malicious Users Can Drain The Assets Of Auto Compound Vault

high

Underlying assets stealing in `AutoPxGmx` and `AutoPxGlp` via share price manipulation

high

fee loss in AutoPxGmx and AutoPxGlp and reward loss in AutoPxGlp by calling PirexRewards.claim(pxGmx/pxGpl, AutoPx*) directly which transfers rewards to AutoPx* pool without compound logic get executed and fee calculation logic and pxGmx wouldn't be exe

medium

Assets may be lost when calling unprotected `AutoPxGlp::compound` function

medium

Deposit Feature Of The Vault Will Break If Update To A New Platform

medium

broken logic in configureGmxState() of PirexGmx contract because it doesn't properly call safeApprove() for stakedGmx address

medium

_calculateRewards() in PirexGmx don't handle reward calculation properly, and it would revert when totalSupply() is zero which will cause claimRewards() to revert if one of 4 rewardTracker's totalSupply was zero

medium

Reward tokens mismanagement can cause users losing rewards

LSD Network - Stakehouse contest

LSD Network - Stakehouse contest

10,860.28 USDC • 10 total findings • Code4rena • unforgiven

gold

high

Incorrect accounting in SyndicateRewardsProcessor results in any LP token holder being able to steal other LP tokens holder's ETH from the fees and MEV vault.

high

Sender transferring GiantMevAndFeesPool tokens can afterward experience pool DOS and orphaning of future rewards

high

possible reentrancy and fund theft in withdrawDETH() of GiantSavETHVaultPool because there is no whitelist check for user provided Vaults and there is no reentrancy defnece

high

fund lose in function bringUnusedETHBackIntoGiantPool() of GiantSavETHVaultPool ETH gets back to giant pool but the value of idleETH don't increase

high

User lose his remaining rewards in GiantMevAndFeesPool when new deposits happen because _onDepositETH() set claimed[][] to max without transferring user remaining rewards

high

Giant pools can be drained due to weak vault authenticity check

high

Old stakers can steal deposits of new stakers in `StakingFundsVault`

high

withdrawETH() in GiantPoolBase don't call _distributeETHRewardsToUserForToken() or _onWithdraw() which would make users to lose their remaining rewards

medium

Freezing of funds - Hacker can prevent users withdraws in giant pools

medium

Withdrawing wrong LPToken from GiantPool leads to loss of funds

Sep '22

Y2k Finance contest

Y2k Finance contest

1,626.32 USDC • 6 total findings • Code4rena • unforgiven

#8

high

Users who deposit in one vault can lose all deposits and receive nothing when counterparty vault has no deposits

high

Depeg event can happen at incorrect price

medium

User fund lost because they can't withdraw() their funds before epoch startTime and they have to stuck in positions that become unprofitable even when epoch is not started

medium

`timewindow` can be changed unexpectedly that blocks users from calling `deposit` function

medium

StakingRewards: recoverERC20() can be used as a backdoor by the owner to retrieve rewardsToken

medium

Different Oracle issues can return outdated prices

FEI and TRIBE Redemption contest

FEI and TRIBE Redemption contest

38.41 USDC • Code4rena • unforgiven

#9

Nouns Builder contest

Nouns Builder contest

5.61 USDC • 1 total finding • Code4rena • unforgiven

#108

medium

Founders can receive less tokens that expected

Jul '22

Fractional v2 contest

Fractional v2 contest

939.85 USDC • 3 total findings • Code4rena • unforgiven

#21

high

Vault implementation can be destroyed leading to loss of all assets

medium

Delegate call in `Vault#_execute` can alter Vault's ownership

medium

Buyout Module: `redeem`ing before the update of totalSupply will make buyout's current state success

Jun '22

Putty contest

Putty contest

1,744.06 USDC • 6 total findings • Code4rena • unforgiven

#9

medium

Order duration can be set to 0 by Malicious maker

medium

Order cancellation is prone to frontrunning and is dependent on a centralized database

medium

Putty position tokens may be minted to non ERC721 receivers

medium

The contract serves as a flashloan pool without fee

medium

`fee` can change without the consent of users

medium

Malicious Token Contracts May Lead To Locking Orders

Nibbl contest

Nibbl contest

2,368.15 USDC • 1 total finding • Code4rena • unforgiven

#4

medium

Reentrancy bug in Basket's withdraw multiple tokens function which gives attacker ability to transfer basket ownership and spend it but withdraw all the tokens out of basket

Yieldy contest

Yieldy contest

2,635.73 USDC • 3 total findings • Code4rena • unforgiven

#6

medium

token transfers in LiquidityReserve and Staking contract don't support deflationary ERC20 tokens, and user funds can be lost if stacking token was deflationary

medium

It's possible to perform DOS and fund lose in Stacking by transferring tokens directly to contract

medium

User fund lose in addLiquidity() of LiquidityReserve by increasing (totalLockedValue / totalSupply()) to very large number by attacker

Illuminate contest

Illuminate contest

1,544.42 USDC • 9 total findings • Code4rena • unforgiven

#10

high

Tempus lend method wrongly calculates amount of iPT tokens to mint

high

Incorrect implementation of APWine and Tempus `redeem`

high

Able to mint any amount of PT

high

Funds may be stuck when `redeeming` for Illuminate

high

Illuminate PT redeeming allows for burning from other accounts

high

[H-05] Not minting iPTs for lenders in several lend functions

medium

Sandwich attacks are possible as there is no slippage control option in Marketplace and in Lender yield swaps

medium

`Lender.mint()` May Take The Illuminate PT As Input Which Will Transfer And Mint More Illuminate PT Cause an Infinite Supply

medium

Centralisation Risk: Admin Can Change Important Variables To Steal Funds

Badger-Vested-Aura contest

Badger-Vested-Aura contest

5,733.2 USDC • 4 total findings • Code4rena • unforgiven

gold

high

auraBAL can be stuck into the Strategy contract

high

attacker can call sweepRewardToken() when `bribesProcessor==0` and reward funds will be lost because there is no check in sweepRewardToken() and _handleRewardTransfer() and _sendTokenToBribesProcessor()

medium

`_harvest` has no slippage protection when swapping `auraBAL` for `AURA`

medium

Badger rewards from Hidden Hand can permanently prevent Strategy from receiving bribes

Infinity NFT Marketplace contest

Infinity NFT Marketplace contest

6,853.32 USDC • 6 total findings • Code4rena • unforgiven

silver

high

Lose of funds in matchOneToManyOrders() and takeOrders() and matchOrders() because code don't check that different ids in one collection are different, so it's possible to sell one id multiple time instead of selling multiple id one time in one collection

high

Sellers may lose NFTs when orders is matched with `matchOrders()`

high

Overpayment of native ETH is not refunded to buyer

high

Maker buy order with no specified NFT tokenIds may get fulfilled in `matchOneToManyOrders` without receiving any NFT

high

Accumulated ETH fees of InfinityExchange cannot be retrieved

medium

fund lose or griefing in all order matching functions [matchOneToOneOrders(), matchOneToManyOrders(), matchOrders(), takeMultipleOneOrders(), takeOrders()] because condition (seller != buyer ) is not checked in any of them

Connext Amarok contest

Connext Amarok contest

16,616.39 USDC • 5 total findings • Code4rena • unforgiven

silver

high

In execute() the amount routers pay is what user signed, but in _reconcile() the amount routers get is what nomad sends and this two amount are not necessary equal because of slippage in original domain

medium

Router Owner Could Be Rugged By Admin

medium

division rounding error in _handleExecuteLiquidity() and _reconcile() make routerBalances and contract fund balance to get out of sync and cause fund lose

medium

attacker can perform griefing for process() in PromiseRouter by reverting calls to callback() in callbackAddress

medium

in reimburseLiquidityFees() of SponserVault contract swaps tokens without slippage limit so its possible to perform sandwich attack and it create MEV

Notional x Index Coop

Notional x Index Coop

12,608.65 USDC • 3 total findings • Code4rena • unforgiven

silver

medium

fCash of the wrong maturity and asset can be sent to wrapper address before wrapper is deployed

medium

deposit() and mint() and _redeemInternal() in wfCashERC4626() will revert for all fcash that asset token is underlying token because they always call _mintInternal() with useUnderlying==True

medium

The logic of _isUnderlying() in NotionalTradeModule is wrong which will cause mintFCashPosition() and redeemFCashPosition() revert on `fcash` tokens which asset token is underlying token (asset.tokenType == TokenType.NonMintable)

May '22

Backd Tokenomics contest

Backd Tokenomics contest

1,634.57 USDC • 2 total findings • Code4rena • unforgiven

#14

medium

it's possible to initialize contract BkdLocker for multiple times by sending startBoost=0 and each time different values for other parameters

medium

Users can claim more fees than expected if governance migrates current rewardToken again by fault.

veToken Finance contest

veToken Finance contest

6,411.2 USDT • 6 total findings • Code4rena • unforgiven

bronze

medium

Duplicate LP token could lead to incorrect deposits

medium

`VE3DRewardPool` and `VE3DLocker` adds to an unbounded array which may potentially lock all rewards in the contract

medium

Incorrectly set ```_maxTime``` to be in line with the locking ```maxTime``` of each veToken could render the ```deposit``` of this contract to be unfunctional or even freeze assets inside the contract

medium

in notifyRewardAmount() of VE3DRewardPool and BaseRewardPool some tokes will be locked and not distributed becasue of rounding error

medium

Unused rewards(because of totalSupply()==0 for some period) will be locked forever in VE3DRewardPool and BaseRewardPool

medium

deposited staking tokens can be lost if rewards token info added by mistake in addReward() in VE3DRewardPool and there is no checking to ensure this would not happen (ve3Token for one reward was equal to stacking token)

Velodrome Finance contest

Velodrome Finance contest

4,249 USDC • 5 total findings • Code4rena • unforgiven

#7

high

User rewards stop accruing after any _writeCheckpoint calling action

medium

temporary DOS by calling notifyRewardAmount() in Bribe/Gauge with malicious tokens

medium

Wrong reward distribution in Bribe because deliverReward() won't set tokenRewardsPerEpoch[token][epochStart] to 0

medium

Rewards can be locked in Bribe contract because distributing them is depend of base token reward amount and Gauge.deliverBribes() is not get called always by Voter.distribute()

medium

Bribe.sol is not meant to handle fee-on-transfer tokens

Rubicon contest

Rubicon contest

685.29 USDC • 6 total findings • Code4rena • unforgiven

#20

high

First depositor can break minting of shares

medium

Cannot deposit to BathToken if token is Deflationary Token (BathHouse.sol)

medium

Strategists can take more rewards than they should using the function strategistBootyClaim().

medium

Missing checks allow strategists to steal all fund via `tailOff`

medium

Outstanding Amount Of A Pool Reduced Although Tokens Are Not Repaid

medium

Wrong DOMAIN_SEPARATOR

Aura Finance contest

Aura Finance contest

233.28 USDC • Code4rena • unforgiven

#39

FactoryDAO contest

FactoryDAO contest

2,298.51 DAI • 3 total findings • Code4rena • unforgiven

#4

high

SpeedBumpPriceGate: Excess ether did not return to the user

medium

Verification should be leafed based and not address based

medium

getRewards() in PermissionlessBasicPoolFactory calculate wrong reward amount for receiptId==0

Forgotten Runes Warrior Guild contest

Forgotten Runes Warrior Guild contest

589.03 USDC • 2 total findings • Code4rena • unforgiven

#18

medium

The owner can mint all of the NFTs.

medium

Many unbounded and under-constrained variables in the system can lead to unfair price or DoS

Apr '22

PoolTogether Aave v3 contest

PoolTogether Aave v3 contest

1,914.48 USDC • 2 total findings • Code4rena • unforgiven

bronze

high

[WP-H1] A malicious early user/attacker can manipulate the vault's pricePerShare to take an unfair share of future users' deposits

medium

User fund loss in supplyTokenTo() because of rounding

Mimo DeFi contest

Mimo DeFi contest

8,173.91 USDC • 2 total findings • Code4rena • unforgiven

silver

high

Fund loss or theft by attacker with creating a flash loan and setting SuperVault as receiver so executeOperation() will be get called by lendingPool but with attackers specified params

medium

Users can use updateBoost function to claim unfairly large rewards from liquidity mining contracts for themselves at cost of other users.

AbraNFT contest

AbraNFT contest

72.47 MIM • Code4rena • unforgiven

#41

Backd contest

Backd contest

18,657.22 USDC • 2 total findings • Code4rena • unforgiven

gold

high

User can steal all rewards due to checkpoint after transfer

high

function lockFunds in TopUpActionLibrary can cause serious fund lose. fee and Capped bypass. It's not calling stakerVault.increaseActionLockedBalance when transfers stakes.