Golom contest - rajatbeladiya's results

An NFT marketplace that offers the lowest industry fee, a publicly available order-book along with analytical tools.

General Information

Platform: Code4rena

Start Date: 26/07/2022

Pot Size: $75,000 USDC

Total HM: 29

Participants: 179

Period: 6 days

Judge: LSDan

Total Solo HM: 6

Id: 148

League: ETH

Golom

Findings Distribution

Researcher Performance

Rank: 63/179

Findings: 4

Award: $181.99

🌟 Selected for report: 0

πŸš€ Solo Findings: 0

Findings Information

Awards

93.2805 USDC - $93.28

Labels

bug
duplicate
3 (High Risk)

External Links

#0 - KenzoAgada

2022-08-02T09:24:56Z

Duplicate of #611

Awards

26.7695 USDC - $26.77

Labels

bug
duplicate
3 (High Risk)

External Links

Lines of code

https://github.com/code-423n4/2022-07-golom/blob/e5efa8f9d6dda92a90b8b2c4902320acf0c26816/contracts/vote-escrow/VoteEscrowDelegation.sol#L71-L89 https://github.com/code-423n4/2022-07-golom/blob/e5efa8f9d6dda92a90b8b2c4902320acf0c26816/contracts/vote-escrow/VoteEscrowDelegation.sol#L101

Vulnerability details

Impact

numCheckPoints is used to calculate checkpoints for each delegated tokenId

https://github.com/code-423n4/2022-07-golom/blob/e5efa8f9d6dda92a90b8b2c4902320acf0c26816/contracts/vote-escrow/VoteEscrowDelegation.sol#L101

here, initial nCheckpoints is set to zero, substract it to by 1 will throw Underflow error. So delegate will not work

Proof of Concept

it.only('should delegate', async () => { let ve_underlying_amount = ethers.utils.parseEther('10'); let ve_underlying_approve_amount = ethers.utils.parseUnits('10', 28); await golomToken.mint(maker.address, ve_underlying_approve_amount); await golomToken.approve(voteEscrow.address, ve_underlying_approve_amount); const lockDuration = 365 * 24 * 3600 * 4; // 4 year const rewards_starts_at = 2659187519; await ethers.provider.send('evm_setNextBlockTimestamp', [rewards_starts_at]); let re = await voteEscrow.create_lock(ve_underlying_amount, lockDuration); await voteEscrow.delegate(1, 1); // error with underflow error }); `Error: VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation underflowed or overflowed outside of an unchecked block)`

Tools Used

Manual Analysis

add below check to _writeCheckpoint

Checkpoint memory oldCheckpoint; if (nCheckpoints > 0) { oldCheckpoint = checkpoints[toTokenId][nCheckpoints - 1]; }

#0 - KenzoAgada

2022-08-02T09:19:04Z

Duplicate of #630

Awards

26.7695 USDC - $26.77

Labels

bug
duplicate
3 (High Risk)

External Links

Lines of code

https://github.com/code-423n4/2022-07-golom/blob/e5efa8f9d6dda92a90b8b2c4902320acf0c26816/contracts/vote-escrow/VoteEscrowDelegation.sol#L80 https://github.com/code-423n4/2022-07-golom/blob/e5efa8f9d6dda92a90b8b2c4902320acf0c26816/contracts/vote-escrow/VoteEscrowDelegation.sol#L168-L175

Vulnerability details

Impact

delegate call not checking for existing Ids and pushes same tokenId multiple times which is also used for calculate votes. Votes can play a key role in governance ( did not checked governance contract, as it is not in the scope ), bad actor can manipulate proposals in any way.

Proof of Concept

it.only('should increase vote on same delegate call', async () => { try { let ve_underlying_amount = ethers.utils.parseEther('10'); let ve_underlying_approve_amount = ethers.utils.parseUnits('10', 28); await golomToken.mint(maker.address, ve_underlying_approve_amount); await golomToken.approve(voteEscrow.address, ve_underlying_approve_amount); const lockDuration = 365 * 24 * 3600 * 4; // 4 year const rewards_starts_at = 2659187519; await ethers.provider.send('evm_setNextBlockTimestamp', [rewards_starts_at]); let re = await voteEscrow.create_lock(ve_underlying_amount, lockDuration); await voteEscrow.delegate(1, 1); const votes1 = await voteEscrow.getVotes(1); await voteEscrow.delegate(1, 1); const votes2 = await voteEscrow.getVotes(1); await voteEscrow.delegate(1, 1); const votes3 = await voteEscrow.getVotes(1); console.log('votes1===', Number(votes1)); // 9981963390993345000 console.log('votes2===', Number(votes2)); // 19963926623437730000 console.log('votes3===', Number(votes3)); // 29945889697333154000 } catch (error: any) { console.log('error===', error); } });

Tools Used

Manual Analysis

check for existing delegatedId or keep track using mapping insted of array

#0 - KenzoAgada

2022-08-02T12:00:48Z

Duplicate of #169

add check for referrer and msg.sender can't be same

https://github.com/code-423n4/2022-07-golom/blob/e5efa8f9d6dda92a90b8b2c4902320acf0c26816/contracts/core/GolomTrader.sol#L387-L394

same address will intiate two different transactions.

add function to withdraw eth

https://github.com/code-423n4/2022-07-golom/blob/e5efa8f9d6dda92a90b8b2c4902320acf0c26816/contracts/core/GolomTrader.sol#L217

here msg.value can be more than needed. Add function to windraw eth which can be extra deposited eth or accidently sent to this contract .

multiply before divide

https://github.com/code-423n4/2022-07-golom/blob/e5efa8f9d6dda92a90b8b2c4902320acf0c26816/contracts/core/GolomTrader.sol#L242 https://github.com/code-423n4/2022-07-golom/blob/e5efa8f9d6dda92a90b8b2c4902320acf0c26816/contracts/core/GolomTrader.sol#L269 https://github.com/code-423n4/2022-07-golom/blob/e5efa8f9d6dda92a90b8b2c4902320acf0c26816/contracts/core/GolomTrader.sol#L381

Solidity integer division might truncate. As a result, performing multiplication before division can sometimes avoid loss of precision.

Unhandled return values of transfer for ERC20 transfer

https://github.com/code-423n4/2022-07-golom/blob/e5efa8f9d6dda92a90b8b2c4902320acf0c26816/contracts/core/GolomTrader.sol#L382 https://github.com/code-423n4/2022-07-golom/blob/e5efa8f9d6dda92a90b8b2c4902320acf0c26816/contracts/rewards/RewardDistributor.sol#L151

Not checking return values of transfer for WETH/ERC20 could lead to loss of user's fund on transfer failure. ERC20 implementations are not always consistent. Some implementations of transfer and transferFrom could return β€˜false’ on failure instead of reverting. It is safer to wrap such calls into require() statements to these failures.

Unlocked pragma

https://github.com/code-423n4/2022-07-golom/blob/e5efa8f9d6dda92a90b8b2c4902320acf0c26816/contracts/governance/GolomToken.sol#L2

GolomToken has pragma solidity version number with ^0.8.11. The caret (^) points to unlocked pragma, meaning compiler will use the specified version or above. It's good practice to use specific solidity version to know compiler bug fixes and optimisations were enabled at the time of compiling the contract.

Zero address validation

https://github.com/code-423n4/2022-07-golom/blob/e5efa8f9d6dda92a90b8b2c4902320acf0c26816/contracts/vote-escrow/VoteEscrowCore.sol#L868

add zero address check validation

remove unnecessary code

https://github.com/code-423n4/2022-07-golom/blob/e5efa8f9d6dda92a90b8b2c4902320acf0c26816/contracts/vote-escrow/VoteEscrowDelegation.sol#L218

remove unnecessary commented code

add clear error message

https://github.com/code-423n4/2022-07-golom/blob/e5efa8f9d6dda92a90b8b2c4902320acf0c26816/contracts/core/GolomTrader.sol#L217

it could be Insufficient ETH

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