VTVL contest - dic0de's results

Building no-code token management tools to empower web3 founders and investors, starting with token vesting.

General Information

Platform: Code4rena

Start Date: 20/09/2022

Pot Size: $30,000 USDC

Total HM: 12

Participants: 198

Period: 3 days

Judge: 0xean

Total Solo HM: 2

Id: 164

League: ETH

VTVL

Findings Distribution

Researcher Performance

Rank: 150/198

Findings: 1

Award: $18.86

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

18.8574 USDC - $18.86

Labels

bug
enhancement
QA (Quality Assurance)
sponsor disputed

External Links

Lines of code

https://github.com/code-423n4/2022-09-vtvl/blob/f68b7f3e61dad0d873b5b5a1e8126b839afeab5f/contracts/AccessProtected.sol#L39-L43

Vulnerability details

Impact

The AccessProtected contract is used to add and govern the admin access control of the VTVLVesting contract. The deployer of the contract becomes the admin and has the ability of adding other admins via the setAdmin () function https://github.com/code-423n4/2022-09-vtvl/blob/f68b7f3e61dad0d873b5b5a1e8126b839afeab5f/contracts/AccessProtected.sol#L39-L43. The setAdmin () function allows admins to create as well as revoke admins. As such, an admin can revoke the deployer of the contract who is as well the contract owner the admin privileges ultimately incapacitating the deployer.

From the contract documentation, it was not envisioned that the deployer admin rights might be revoked as seen here via this statement:

This group initially starts with just having the contract deployer as the owner/admin. They can then add (or remove) other users as administrators, relegating them the same rights.

Moreover, the test cases did not cover this particular edge case and only tested the owner who is the deployer of the contract abilities on creating and revoking other admins.

Proof of Concept

On the VTVLVesting.js test file, add the following test code under Contract Creation:

it('allows the owner to set and unset other user as an admin and the owner can be unset as well', async function() { const [owner, otherOwner] = await ethers.getSigners(); const contract = await deployVestingContract(); // Initially the other owner is not admin expect(await contract.isAdmin(otherOwner.address)).to.equal(false); // They'll become one after we set them as admin await (await contract.setAdmin(otherOwner.address, true)).wait(); expect(await contract.isAdmin(otherOwner.address)).to.equal(true); // And then they'll stop being one right after we unset them await (await contract.setAdmin(owner.address, false)).wait(); expect(await contract.isAdmin(owner.address)).to.equal(false); });

The test will run successfully as the owner will be unset as the admin

Tools Used

#0 - 0xean

2022-09-23T23:22:34Z

The sponsor may choose to dispute this, but based on the documentation provided I agree with the warden that this is unintended.

#1 - lawrencehui

2022-10-07T14:55:26Z

I would argue that this is intended as we did thought about a case that even sole admin can renounce their admin rights to make the contract completely trustless (code-is-law type of style). And we assumed all admins are honest and trusted.

I appreciate warden's comments on the edge case mentioned above and we can adopt the main admin suggestions as an improvement / feature enhancement.

#2 - 0xean

2022-10-09T22:53:08Z

downgrading to QA see #469 for more info.

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