Biconomy Hyphen 2.0 contest - pedroais's results

Next-Gen Multichain Relayer Protocol.

General Information

Platform: Code4rena

Start Date: 10/03/2022

Pot Size: $75,000 USDT

Total HM: 25

Participants: 54

Period: 7 days

Judge: pauliax

Total Solo HM: 10

Id: 97

League: ETH

Biconomy

Findings Distribution

Researcher Performance

Rank: 10/54

Findings: 5

Award: $2,033.26

🌟 Selected for report: 1

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: cmichel

Also found by: PPrieditis, kyliek, pedroais

Labels

bug
duplicate
2 (Med Risk)

Awards

378.2082 USDT - $378.21

External Links

Lines of code

https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/LiquidityProviders.sol#L352

Vulnerability details

Impact

Liquidity provider will be unable to withdraw tokens that were previously supported

Proof of Concept

In liquidityProviders.sol users can provide liquidity only in supported tokens. This is checked when the user provides liquidity and checked again when he withdraws the liquidity.

If a user provides liquidity in a supported token and the token is then removed from the list he won't be able to withdraw the funds.

Supported tokens should only be checked in deposit and not in withdrawal. If the token was never supported the NFT won't be valid so the withdraw function will revert anyways.

I consider this a medium issue : Assets not at direct risk, but the function of the protocol or its availability could be impacted, or leak value with a hypothetical attack path with stated assumptions, but external requirements.

Only check the token is supported when depositing and not in withdrawals.

#0 - ankurdubey521

2022-03-30T16:15:43Z

Duplicate of #54

#1 - pauliax

2022-04-11T13:08:28Z

#54

Findings Information

🌟 Selected for report: throttle

Also found by: IllIllI, Ruhum, cccz, cmichel, danb, pedroais

Labels

bug
duplicate
2 (Med Risk)
sponsor confirmed

Awards

99.257 USDT - $99.26

External Links

Lines of code

https://github.com/code-423n4/2022-03-biconomy/blob/db8a1fdddd02e8cc209a4c73ffbb3de210e4a81a/contracts/hyphen/LiquidityFarming.sol#L169 https://github.com/code-423n4/2022-03-biconomy/blob/db8a1fdddd02e8cc209a4c73ffbb3de210e4a81a/contracts/hyphen/LiquidityFarming.sol#L289

Vulnerability details

Impact

The owner of the contract can lock user principal in liquidity farming

Proof of Concept

The setRewardPerSecond function gives the owner the power to change the rewardPerSecond for the stacking without any maximum amount. The owner could setRewardPerSecond to a very high number for any base token.

https://github.com/code-423n4/2022-03-biconomy/blob/db8a1fdddd02e8cc209a4c73ffbb3de210e4a81a/contracts/hyphen/LiquidityFarming.sol#L169

If the stacker then wants to withdraw their liquidity NFT they are forced to call the updatePool function. This function calls getUpdatedAccTokenPerShare which computes an accumulator variable by adding the different reward amounts multiplied by the time in seconds. If rewardPerSecond is high enough the accumulator can be made close to max uint which will make the arithmetic will revert and the user's principal will be locked.

The math to compute the accumulator is unchecked so it won't revert but if the accumulator is made high enough it will revert when multiplied by the precision constant. https://github.com/code-423n4/2022-03-biconomy/blob/db8a1fdddd02e8cc209a4c73ffbb3de210e4a81a/contracts/hyphen/LiquidityFarming.sol#L274

For example, if rewardPerSecond is set to 2**250 and a few seconds later to 0 the accumulator will be in that order of magnitude, and accumulator * ACC_TOKEN_PRECISION will revert the withdraw transaction.

https://github.com/code-423n4/2022-03-biconomy/blob/db8a1fdddd02e8cc209a4c73ffbb3de210e4a81a/contracts/hyphen/LiquidityFarming.sol#L289

I consider this a medium issue given it's a critical attack but it's only performable by the contract's governance.

Add a maximum amount to reward per second to protect from overflows.

Findings Information

🌟 Selected for report: danb

Also found by: benk10, pedroais

Labels

bug
duplicate
2 (Med Risk)

Awards

560.3084 USDT - $560.31

External Links

Lines of code

https://github.com/code-423n4/2022-03-biconomy/blob/db8a1fdddd02e8cc209a4c73ffbb3de210e4a81a/contracts/hyphen/LiquidityFarming.sol#L233

Vulnerability details

Impact

An unbounded loop allows an attacker to lock stacker's principal in liquidity farming

Proof of Concept

In the liquidityFarming contract, deposits can be made for someone without their permission. This should be fine as deposits can only benefit the receiver. The problem is in the withdraw function which loops through all NFTs locked by the user until it finds the desired one.

An attacker could deposit multiple NFTS with dust amounts (just some wei of base token for each nft) to make the withdrawal loop very big and surpass the block gas limit. The receiver could be locked from withdrawing their true principal.

https://github.com/code-423n4/2022-03-biconomy/blob/db8a1fdddd02e8cc209a4c73ffbb3de210e4a81a/contracts/hyphen/LiquidityFarming.sol#L233

#0 - ankurdubey521

2022-03-30T09:43:33Z

Duplicate of #24

Findings Information

🌟 Selected for report: pedroais

Also found by: WatchPug

Labels

bug
2 (Med Risk)
sponsor disputed

Awards

933.8474 USDT - $933.85

External Links

Lines of code

https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/LiquidityPool.sol#L171 https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/LiquidityPool.sol#L273

Vulnerability details

Impact

Detailed description of the impact of this finding.

Proof of Concept

When a user calls the deposit function the reward amount is calculated and an event is emited with amount+reward as the transfer amount. The function checks amount is smaller than the max amount.

An executor then listens to this event and calls sendFundsToUser with rewards + amount as the amount parameter. This function checks amount+reward is smaller than max amount.

This is a problem because the amount transferred may be in the limit but amount + reward could pass the limit and the executor won't be able to send the transaction. The user will lose the funds. Both checks should be made with the reward or without the reward but the checks should be the same for this not to happen.

Step by step : Max transfer is set to 50 for token A Bob transfers 49 tokens, this will pass since 49<50. The reward is calculated in 2 tokens. The executor then calls sendFundsToUser with 52. This transaction will revert and user will lose their tokens.

This value of amount includes rewards but the previous check didn't include rewards: https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/LiquidityPool.sol#L273

Both checks should be made over the same amount = amount + rewards

#0 - ankurdubey521

2022-03-30T10:45:12Z

We handle this issue by setting a slightly larger limit in the transfer config of each token on the destination chain.

#1 - ankurdubey521

2022-03-30T10:46:34Z

Also duplicate of #142

#2 - pauliax

2022-04-28T20:28:43Z

Even though the sponsor is already aware of and mitigates this issue, it could still be fixed algorithmically to prevent accidental loss of funds. I am leaving this as of medium severity.

Awards

61.6265 USDT - $61.63

Labels

bug
G (Gas Optimization)

External Links

Variables that are set in the initializer and can't change (there is no method to change them ) should be immutable to save gas : https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/LiquidityFarming.sol#L26 https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/LiquidityFarming.sol#L27

Variables that weigh less than 32 bytes should be grouped together to save storage slots (and gas): https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/LiquidityFarming.sol#L29 (Address is 20 bytes and bool is 1 byte, they should be declared next to each other in the struct to save a slot)

Public functions that are never used inside the SAME contract should be external to save gas : https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/LiquidityFarming.sol#L169

https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/LiquidityFarming.sol#L329

https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/LiquidityFarming.sol#L333

https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/LiquidityFarming.sol#L83

https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/LiquidityPool.sol#L107

https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/LiquidityPool.sol#L113

https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/LiquidityProviders.sol#L78

https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/LiquidityProviders.sol#L96

https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/LiquidityProviders.sol#L100

https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/LiquidityProviders.sol#L104

https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/LiquidityProviders.sol#L108

https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/LiquidityProviders.sol#L127

https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/LiquidityProviders.sol#L131

Unnecessary checks :

Checking approval is useless. If the approval isn't made the safeTransfer will revert anyway:

https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/LiquidityFarming.sol#L200

Same for this one : https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/LiquidityProviders.sol#L270

If the NFT is already staked then it will be held inside the contract and the transfer will fail so checking this does nothing : https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/LiquidityFarming.sol#L211

If the contract doesn't have enough balance the transfer will fail and success will be false which will make the transaction revert. This check does nothing : https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/LiquidityPool.sol#L288

The same for this one if the balance is not enough safeTransfer will revert : https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/LiquidityPool.sol#L292

Instead of setting = false delete could be used wich will free storage and return some gas : https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/token/TokenManager.sol#L101

#0 - pauliax

2022-05-09T09:37:26Z

1 is not valid and 3 is valid only in some cases.

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter