Boot Finance contest - pauliax's results

Custom DEX AMM for Defi Projects

General Information

Platform: Code4rena

Start Date: 04/11/2021

Pot Size: $50,000 USDC

Total HM: 20

Participants: 28

Period: 7 days

Judge: 0xean

Total Solo HM: 11

Id: 51

League: ETH

Boot Finance

Findings Distribution

Researcher Performance

Rank: 4/28

Findings: 8

Award: $3,800.85

🌟 Selected for report: 11

🚀 Solo Findings: 1

Findings Information

🌟 Selected for report: gpersoon

Also found by: elprofesor, fr0zn, pauliax

Labels

bug
duplicate
3 (High Risk)

Awards

529.9131 USDC - $529.91

External Links

Handle

pauliax

Vulnerability details

Impact

When checking if a user is already validated, it relies on the amount to be 0. However, this check can be bypassed by claiming all your airdrop to reduce your amount to 0 and then validating yourself again to refill your allocation.

function claim prevents that by having this assertion: assert(airdrop[msg.sender].amount - claimable != 0); however, this check is missing in claimExact so you can use it to exploit the system.

A solution could be to simply not to rely on the amount but require that validated[msg.sender] == 0.

#0 - chickenpie347

2022-01-04T02:26:58Z

Duplicate of #101

Findings Information

🌟 Selected for report: nathaniel

Also found by: WatchPug, leastwood, pauliax

Labels

bug
duplicate
3 (High Risk)

Awards

529.9131 USDC - $529.91

External Links

Handle

pauliax

Vulnerability details

Impact

Vest function can be accessed by anyone. It accepts arbitrary _beneficiary and pushes new vesting to the array of this beneficiary timelocks. As a malicious actor I can block any user by just invoking vest function with a tiny amount of vest token. The problem may arise later when it iterates over all the timelocks in a loop. This timelocks array does not have any boundaries so it eventually can grow so large as to make operations of the contract cost too much gas to fit in a block. The execution may exceed the block gas limit, consume all the gas provided, and fail.

A simple solution would be to specify the exact timelock id (or an array of ids) when claiming or revoking the timelock. Another possible solution is to add auth restrictions on the vest function but it adds extra dependency trust on admins.

#0 - chickenpie347

2022-01-04T02:23:24Z

Duplicate of #120

Findings Information

🌟 Selected for report: Reigada

Also found by: 0v3rf10w, Ruhum, WatchPug, cmichel, defsec, loop, pauliax

Labels

bug
duplicate
2 (Med Risk)

Awards

52.1514 USDC - $52.15

External Links

Handle

pauliax

Vulnerability details

Impact

Contracts (e.g. InvestorDistribution, AirdropDistribution, Vesting) have declared to use safe ERC20 library: using SafeERC20 for IERC20;

However, when actually making the approvals or transfers, they make no use of this library and rely on simple standard functions, e.g.: IERC20 public mainToken; mainToken.approve(address(vestLock), 2**256-1); mainToken.transfer(msg.sender, claimable_to_send); vestingToken.transferFrom(msg.sender, address(this), _amount);

A similar issue was reported in a previous contest and was assigned a severity of low: https://github.com/code-423n4/2021-06-realitycards-findings/issues/105 https://github.com/code-423n4/2021-09-bvecvx-findings/issues/33

Although you probably trust the implementation of this mainToken but for extra precaution, you can use this safe library nevertheless or remove the declaration to remove the confusion otherwise. Also, please note that safeApprove is deprecated in favor of safeIncreaseAllowance and safeDecreaseAllowance: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/566a774222707e424896c0c390a84dc3c13bdcb2/contracts/token/ERC20/utils/SafeERC20.sol#L38

#0 - chickenpie347

2022-01-04T02:22:15Z

Duplicate of #31

Findings Information

🌟 Selected for report: pauliax

Labels

bug
2 (Med Risk)
sponsor acknowledged

Awards

872.285 USDC - $872.28

External Links

Handle

pauliax

Vulnerability details

Impact

Public sale has a constraint that for the first 4 weeks only NFT holders can access the sale: if (currentEra < firstPublicEra) { require(nft.balanceOf(msg.sender) > 0, "You need NFT to participate in the sale."); }

However, this check can be easily bypassed with the help of flash loans. You can borrow the NFT, participate in the sale and then return this NFT in one transaction. It takes only 1 NFT that could be flashloaned again and again to give access to the sale for everyone (burnEtherForMember).

I am not sure what could be the most elegant solution to this problem. You may consider transferring and locking this NFT for at least 1 block but then the user will need to do an extra tx to retrieve it back. You may consider taking a snapshot of user balances so the same NFT can be used by one address only but then this NFT will lose its extra benefit of selling it during the pre-sale when it acts as a pre-sale token. You may consider checking that the caller is EOA but again there are ways to bypass that too.

Findings Information

🌟 Selected for report: gpersoon

Also found by: WatchPug, cmichel, hyh, leastwood, pauliax

Labels

bug
duplicate
2 (Med Risk)

Awards

85.8459 USDC - $85.85

External Links

Handle

pauliax

Vulnerability details

Impact

function vest has a parameter _isRevocable that is tied to the account address of _beneficiary. because anyone can call vest, it allows overriding benRevocable as many times as you want.

I see several potential problems with this:

  1. _isRevocable sets global flag to the account so this becomes pretty useless as anyone can invoke function vest and toggle it on/off.
  2. as a beneficiary I do not want my timelocks to be revoked so I can monitor the mempool and once I see that someone wants to revoke me, I send a new vesting tx and set my benRevocable status to irrevocable.

One solution could be to tie revocable to the timelock, not the account so every individual vesting can or can't be revoked later. Another solution would be to introduce an admin-only function that can set the revocable status of the user. There are many more possible solutions, it is up to you to decide which one is the most appropriate in your case.

#0 - chickenpie347

2022-01-04T02:23:53Z

Duplicate of #132

Findings Information

🌟 Selected for report: defsec

Also found by: Reigada, Ruhum, elprofesor, mics, pants, pauliax

Labels

bug
duplicate
2 (Med Risk)

Awards

85.8459 USDC - $85.85

External Links

Handle

pauliax

Vulnerability details

Impact

function setAdmin allows the current admin to change it to a different address. If accidentally an invalid address is used for which they do not have the private key, then it cannot be corrected and none of the functions that require admin caller can be executed. A similar issue was reported in a previous contest and was assigned a severity of medium: https://github.com/code-423n4/2021-06-realitycards-findings/issues/105

Consider either introducing a two-step process or making a test call to the new admin before updating it.

#0 - chickenpie347

2021-11-16T14:09:09Z

Addressed in #90

#1 - CloudEllie

2022-01-05T02:17:16Z

Looks like #35 is the primary here.

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