FIAT DAO veFDT contest - wagmi's results

Unlock liquidity for your DeFi fixed income assets.

General Information

Platform: Code4rena

Start Date: 12/08/2022

Pot Size: $35,000 USDC

Total HM: 10

Participants: 126

Period: 3 days

Judge: Justin Goro

Total Solo HM: 3

Id: 154

League: ETH

FIAT DAO

Findings Distribution

Researcher Performance

Rank: 37/126

Findings: 2

Award: $107.61

🌟 Selected for report: 0

πŸš€ Solo Findings: 0

Findings Information

🌟 Selected for report: Aymen0909

Also found by: 0xSky, 0xf15ers, CertoraInc, JohnSmith, auditor0517, bin2chen, csanuragjain, scaraven, tabish, wagmi, yixxas

Labels

bug
duplicate
2 (Med Risk)
old-submission-method

Awards

77.7206 USDC - $77.72

External Links

Lines of code

https://github.com/code-423n4/2022-08-fiatdao/blob/fece3bdb79ccacb501099c24b60312cd0b2e4bb2/contracts/VotingEscrow.sol#L513

Vulnerability details

Impact

In increaseUnlockTime() function, in case it’s undelegated lock, it calls _checkpoint for msg.sender with oldLocked and locked_. But actually, these 2 locks oldLocked and locked_ are the same. It makes the logic in _checkpoint() function works incorrectly.

Proof of Concept

Line 507-515

locked_.end = unlock_time;
locked[msg.sender] = locked_;
if (locked_.delegatee == msg.sender) {
    // Undelegated lock
    require(oldUnlockTime > block.timestamp, "Lock expired");
    LockedBalance memory oldLocked = _copyLock(locked_);
    oldLocked.end = unlock_time; // @audit should be oldUnlockTime
    _checkpoint(msg.sender, oldLocked, locked_);
}

Value end of locked_ is updated to unlock_time in line 507 and line 512-513 is copy value of locked_ to oldLocked and also update value end to unlock_time. So basically, values of locked_ and oldLocked are identical.

Tools Used

Manual Review

Update logic, value end of oldLocked should be oldUnlockTime

oldLocked.end = oldUnlockTime;

#0 - lacoop6tu

2022-08-16T13:28:01Z

Duplicate of #217

Lines of code

https://github.com/code-423n4/2022-08-fiatdao/blob/fece3bdb79ccacb501099c24b60312cd0b2e4bb2/contracts/VotingEscrow.sol#L257-L264 https://github.com/code-423n4/2022-08-fiatdao/blob/fece3bdb79ccacb501099c24b60312cd0b2e4bb2/contracts/VotingEscrow.sol#L372

Vulnerability details

Impact

In function _checkpoint(), new values of userPointHistory and pointHistory are override old values instead of appending to the end of the list, i.e creating new element.

The result is if we try to get balanceOf or totalSupply at current block number, it just return wrong value because values of globalEpoch is overrided.

Proof of Concept

Line 257-264

if (uEpoch == 0) {
    userPointHistory[_addr][uEpoch + 1] = userOldPoint;
}

userPointEpoch[_addr] = uEpoch + 1;
userNewPoint.ts = block.timestamp;
userNewPoint.blk = block.number;
userPointHistory[_addr][uEpoch + 1] = userNewPoint;

When uEpoch == 0, values of userPointHistory with index = uEpoch + 1 is updated to userOldPoint but in line 264, values of userPointHistory with index = uEpoch + 1 is overrided to userNewPoint which basically makes line 257-259 has no meaning.

Similarly issue with value of pointHistory[epoch] in line 372

Tools Used

Manual Review

Update logic of _checkpoint(), for example, use ++ operator to make sure epoch is increased each time it appends new element.

#0 - lacoop6tu

2022-08-16T13:35:24Z

Lines 257-259 are actually meaningless and are not causing any error/side effects, they can be removed. in mStable impl, they used a dynamic array so they had to push an empty point with the first index, while we are using a fixed one which is already there. But i don't see the similarity for "Similarly issue with value of pointHistory[epoch] in line 372"

#1 - elnilz

2022-08-17T12:35:43Z

so essentially the issue is just that lines 257-259 are unnecessary but don't affect in any way the proper functioning of the system. that's why I think its a QA severity

#2 - gititGoro

2022-09-04T22:01:48Z

Duplicate of #316

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