Paladin - Warden Pledges contest - KingNFT's results

A governance lending protocol transforming users voting power into a new money lego.

General Information

Platform: Code4rena

Start Date: 27/10/2022

Pot Size: $33,500 USDC

Total HM: 8

Participants: 96

Period: 3 days

Judge: kirk-baird

Total Solo HM: 1

Id: 176

League: ETH

Paladin

Findings Distribution

Researcher Performance

Rank: 10/96

Findings: 1

Award: $754.53

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: Chom

Also found by: Jeiwan, KingNFT, Picodes

Labels

bug
2 (Med Risk)
satisfactory
edited-by-warden
duplicate-91

Awards

754.535 USDC - $754.53

External Links

Lines of code

https://github.com/code-423n4/2022-10-paladin/blob/d6d0c0e57ad80f15e9691086c9c7270d4ccfe0e6/contracts/WardenPledge.sol#L325

Vulnerability details

Impact

The reward token reserved in pledge is not enough, funds will be used up before the targetVotes is reached.

Proof of Concept

The 'totalRewardAmount ' is calculated based on current votingEscrow token balanceOf receiver.

function createPledge( // ... ) external whenNotPaused nonReentrant returns(uint256){ // ... vars.votesDifference = targetVotes - votingEscrow.balanceOf(receiver); vars.totalRewardAmount = (rewardPerVote * vars.votesDifference * vars.duration) / UNIT; // ... }

But votingEscrow balance would decrease over time, which makes the actual votesDifference increase during pledge

@external @view def balanceOf(addr: address, _t: uint256 = block.timestamp) -> uint256: _epoch: uint256 = self.user_point_epoch[addr] if _epoch == 0: return 0 else: last_point: Point = self.user_point_history[addr][_epoch] last_point.bias -= last_point.slope * convert(_t - last_point.ts, int128) if last_point.bias < 0: last_point.bias = 0 return convert(last_point.bias, uint256)

reference from https://etherscan.io/address/0x5f3b5DfEb7B28CDbD7FAba78963EE202a494e2A2#code

This makes reserved fund is not enough to reach target votes

Tools Used

VS Code

Use endTimestamp to calculate votingEscrow token balance

function createPledge( // ... ) external whenNotPaused nonReentrant returns(uint256){ // ... vars.votesDifference = targetVotes - votingEscrow.balanceOf(receiver, endTimestamp); // ... }

#0 - Kogaroshi

2022-10-30T23:44:34Z

Duplicate of #91

#1 - c4-judge

2022-11-10T22:49:19Z

kirk-baird marked the issue as satisfactory

#2 - c4-judge

2022-11-10T22:49:24Z

kirk-baird marked the issue as not a duplicate

#3 - c4-judge

2022-11-10T22:49:38Z

kirk-baird marked the issue as duplicate of #91

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