Boot Finance contest - hyh'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: 15/28

Findings: 3

Award: $698.95

🌟 Selected for report: 7

🚀 Solo Findings: 0

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

hyh

Vulnerability details

Impact

Griefing attack is possible for revoke mechanics by calling vest() with a tiny amount and zero _isRevocable. This will switch revocable off for the whole vesting amount (i.e. the whole set of timelocks flag is being set via last vest call).

And vice versa, whenever the vesting isn't revocable, a beneficiary can send a tiny amount to vest() for himself (i.e. do vest(me, 1 wei, 1)), switching the flag on.

The severity is medium as the attack is reversable this way and revoke() is owner executable only, but there is also a case of malicious owner, who can set _isRevocable to 1 via this vulnerability and surpass vesting via calling revoke() for the addresses associated with him. Both AirdropDistribution and InvestorDistribution call vest with 0 isRevocable, i.e. revoke mechanics isn't a part of standard process now.

Proof of Concept

benRevocable flag works for the whole vestings for an address. It can be switched on and off by anyone sending tiny _amount to vest() function and setting desired state of the flag. The flag is basically meaningless this way as anyone, including beneficiary, can switch it on and off. https://github.com/code-423n4/2021-11-bootfinance/blob/main/vesting/contracts/Vesting.sol#L83

As vest() function to be accessed by Distribution contracts only it is recommended to add an expandable list of allowed Distribution contracts and add an access modifier to vest() https://github.com/code-423n4/2021-11-bootfinance/blob/main/vesting/contracts/Vesting.sol#L73

Now: function vest(address _beneficiary, uint256 _amount, uint256 _isRevocable) external payable whenNotPaused {

To be: function vest(address _beneficiary, uint256 _amount, uint256 _isRevocable) external payable onlyDistribution whenNotPaused {

If manual vest/revoke by an Owner is planned, the Owner to be added to the Distribution list, but also benRevocable should be added to timelocks array and become per timelock based.

Now: struct Timelock { uint256 amount; uint256 releaseTimestamp; } mapping(address => Timelock[]) public timelocks; mapping(address => bool[2]) public benRevocable;

To be: struct Timelock { uint256 amount; uint256 releaseTimestamp; bool[2] benRevocable; } mapping(address => Timelock[]) public timelocks;

revoke() logic should be modified accordingly to affect allowed timelocks only.

#0 - chickenpie347

2021-11-16T13:50:52Z

This has been addressed in #220 and #213 and #132.

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