Party DAO - Arz's results

Protocol for group coordination.

General Information

Platform: Code4rena

Start Date: 31/10/2023

Pot Size: $60,500 USDC

Total HM: 9

Participants: 65

Period: 10 days

Judge: gzeon

Total Solo HM: 2

Id: 301

League: ETH

PartyDAO

Findings Distribution

Researcher Performance

Rank: 4/65

Findings: 2

Award: $1,532.79

🌟 Selected for report: 1

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: Arz

Also found by: HChang26, Vagner

Labels

bug
2 (Med Risk)
primary issue
satisfactory
selected for report
sponsor confirmed
sufficient quality report
M-01

Awards

1380.4196 USDC - $1,380.42

External Links

Lines of code

https://github.com/code-423n4/2023-10-party/blob/b23c65d62a20921c709582b0b76b387f2bb9ebb5/contracts/proposals/ProposalExecutionEngine.sol#L148

Vulnerability details

The executeProposal() function in ProposalExecutionEngine.sol is used to execute different types of proposal call. One of this type is ArbitraryCallsProposal and this type should be able to send ether from the Party's balance or the forwarded ETH attached to this call - msg.value. However, the problem is that the executeProposal() function is not marked as payable and all calls that are sending ether and using msg.value will fail because of that.

Note: Even though this function is delegatecalled from PartyGovernance.sol::execute() which is payable the msg.value is still preserved when delegatecall is used and the function called needs to be payable too.

Impact

All proposal calls that are using attached ether to it will fail and Party's wont be able to execute these types of proposals which can be important.

Proof of Concept

https://github.com/code-423n4/2023-10-party/blob/b23c65d62a20921c709582b0b76b387f2bb9ebb5/contracts/proposals/ProposalExecutionEngine.sol#L146-L148

146:   function executeProposal(
147:     ExecuteProposalParams memory params
148:   ) external onlyDelegateCall returns (bytes memory nextProgressData) { 

As you can see the executeProposal() function is not payable however later it then calls _executeArbitraryCalls():

https://github.com/code-423n4/2023-10-party/blob/b23c65d62a20921c709582b0b76b387f2bb9ebb5/contracts/proposals/ArbitraryCallsProposal.sol#L72-L74

72:  // If we're not allowing arbitrary calls to spend the Party's ETH, only
73:  // allow forwarded ETH attached to the call to be spent.
74:  uint256 ethAvailable = allowArbCallsToSpendPartyEth ? address(this).balance : msg.value;

As you can see and as the comment suggests the call should be able to use the forwarded ether attached to the call and ethAvailable is then used in _executeSingleArbitraryCall() but because the function is not payable the call will revert.

Tools Used

Manual Review

Make the executeProposal() function payable

Assessed type

Payable

#0 - ydspa

2023-11-11T14:30:46Z

seems right, EVM source code

File: core\vm\contract.go
134: func (c *Contract) AsDelegate() *Contract {
135: 	// NOTE: caller must, at all times be a contract. It should never happen
136: 	// that caller is something other than a Contract.
137: 	parent := c.caller.(*Contract)
138: 	c.CallerAddress = parent.CallerAddress
139: 	c.value = parent.value
140: 
141: 	return c
142: }

#1 - c4-pre-sort

2023-11-11T14:30:56Z

ydspa marked the issue as insufficient quality report

#2 - c4-pre-sort

2023-11-11T15:09:56Z

ydspa marked the issue as sufficient quality report

#3 - c4-pre-sort

2023-11-12T08:24:25Z

ydspa marked the issue as primary issue

#4 - c4-sponsor

2023-11-14T20:11:27Z

arr00 (sponsor) confirmed

#5 - c4-judge

2023-11-19T14:45:41Z

gzeon-c4 marked the issue as selected for report

#6 - c4-judge

2023-11-19T14:45:45Z

gzeon-c4 marked the issue as satisfactory

Findings Information

🌟 Selected for report: TresDelinquentes

Also found by: 3docSec, Arz, Bauchibred, D1r3Wolf, J4X, Neon2835, Pechenite, adeolu, chainsnake

Labels

bug
2 (Med Risk)
satisfactory
insufficient quality report
duplicate-127

Awards

152.3655 USDC - $152.37

External Links

Lines of code

https://github.com/code-423n4/2023-10-party/blob/b23c65d62a20921c709582b0b76b387f2bb9ebb5/contracts/crowdfund/ETHCrowdfundBase.sol#L256

Vulnerability details

Because of a finding in the previous contest, the minContribution check is done after the amount is potentially reduced if refunding excess contribution. However this can be a problem if the maxTotalContributions - minTotalContributions is smaller than the minContribution and in some cases the crowdfund can be lost because of this.

Example:

minTotalContributions = 100 ether maxTotalContributions = 102 ether The current totalContributions = 99 ether minContribution amount = 4 ether

When the last contributor wants to contribute he calls the function with 4 ether however the reduced amount will then be 3 ether and the tx will revert because of the minContribution check and the crowdfund will be lost.

Impact

There will be no way to finalize the crowdfund and because of that it will be lost even though it was supposed to be finalized.

Proof of Concept

https://github.com/code-423n4/2023-10-party/blob/b23c65d62a20921c709582b0b76b387f2bb9ebb5/contracts/crowdfund/ETHCrowdfundBase.sol#L240

240:  amount -= refundAmount;

https://github.com/code-423n4/2023-10-party/blob/b23c65d62a20921c709582b0b76b387f2bb9ebb5/contracts/crowdfund/ETHCrowdfundBase.sol#L256

256:  if (amount < minContribution_) {
257:      revert BelowMinimumContributionsError(amount, minContribution_);
258:  }

As you can see the amount is reduced and the check is done after it, the problem arises when the maxTotalContributions - minTotalContributions is smaller than the minContribution which will cause the crowdfund to be lost.

Tools Used

Manual Review

Because we cant move the check before the refund logic, the only way to prevent this is to check if the minContribution is bigger than the maxTotalContributions - minTotalContributions in the initialize function

Assessed type

Other

#0 - ydspa

2023-11-11T06:24:20Z

#1 - c4-pre-sort

2023-11-11T06:24:34Z

ydspa marked the issue as insufficient quality report

#2 - c4-pre-sort

2023-11-11T08:32:57Z

ydspa marked the issue as primary issue

#3 - c4-judge

2023-11-19T14:33:07Z

gzeon-c4 marked the issue as unsatisfactory: Invalid

#4 - c4-judge

2023-11-19T14:40:16Z

gzeon-c4 marked the issue as unsatisfactory: Out of scope

#5 - c4-judge

2023-11-23T14:16:10Z

gzeon-c4 marked the issue as unsatisfactory: Out of scope

#6 - c4-judge

2023-11-23T14:20:08Z

gzeon-c4 marked the issue as satisfactory

#7 - c4-judge

2023-11-23T14:22:52Z

gzeon-c4 marked issue #127 as primary and marked this issue as a duplicate of 127

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