Revolution Protocol - 0xlemon's results

A protocol to empower communities to raise funds, fairly distribute governance, and maximize their impact in the world.

General Information

Platform: Code4rena

Start Date: 13/12/2023

Pot Size: $36,500 USDC

Total HM: 18

Participants: 110

Period: 8 days

Judge: 0xTheC0der

Id: 311

League: ETH

Collective

Findings Distribution

Researcher Performance

Rank: 65/110

Findings: 1

Award: $44.03

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

44.0266 USDC - $44.03

Labels

bug
3 (High Risk)
satisfactory
sufficient quality report
duplicate-210

External Links

Lines of code

https://github.com/code-423n4/2023-12-revolutionprotocol/blob/main/packages/revolution/src/ERC20TokenEmitter.sol#L152-L230

Vulnerability details

Summary

There is leftover ether that will be stuck forever in the ERC20TokenEmitter. This is a result of executing the buyToken function and sending ether as msg.value.

Vulnerability Details

ERC20TokenEmitter::buyToken function is used to buy erc20 votes tokens. If the owner of the contract has set a payment for the creator from setCreatorRateBps function, then there will be ether stuck if the direct payment entropyRateBps is not set to 100%. This happens because when a user sends value to the contract, a small portion of this value is reserved for the builder, purchaseReferral and deployer. Another portion is transferred to the DAO in exchange for minting the user vote tokens, then we have a direct payment for the creator and finally instead of tranferring the creator's left payment, we mint him vote tokens. The problem is exactly in the last step because we mint erc20 tokens for the creator but the value that this erc20 tokens correspond to is left in the contract with no actual way to withdraw it.

Proof of Concept

Here is a test showcasing the issue: Add this test in 2023-12-revolutionprotocol\packages\revolution\test\token-emitter\ERC20TokenEmitter.t.sol and add the console at the top like that: import { Test, console } from "forge-std/Test.sol"; To run this test: forge test --match-contract testStuckEtherAfterBuyToken -vvv (make sure you are in the 2023-12-revolutionprotocol/packages/revolution directory)

function testStuckEtherAfterBuyToken() public { address creatorAddress = makeAddr("creatorAddress"); address owner = erc20TokenEmitter.owner(); vm.startPrank(owner); erc20TokenEmitter.setCreatorsAddress(creatorAddress); erc20TokenEmitter.setCreatorRateBps(1000); // set the creator rate to be 10% erc20TokenEmitter.setEntropyRateBps(500); // 5% direct payment vm.stopPrank(); address user = makeAddr("someUser"); vm.deal(user, 10 ether); address[] memory recipients = new address[](1); recipients[0] = address(1); uint256[] memory bps = new uint256[](1); bps[0] = 10_000; vm.startPrank(user); erc20TokenEmitter.buyToken{ value: 10 ether}( recipients, bps, IERC20TokenEmitter.ProtocolRewardAddresses({ builder: address(0), purchaseReferral: address(0), deployer: address(0) }) ); vm.stopPrank(); console.log(address(erc20TokenEmitter).balance); // 0.9262 ether is left in the contract assert(address(erc20TokenEmitter).balance != 0); }

In this test we see that after executing the buyToken function there is still ether left in the contract that cannot be withdrawn. This happens due to the issue I described above.

Impact

Ether stuck in ERC20TokenEmitter

Tools Used

Manual Review, VS Code, Foundry

To mitigate this issue I recommend adding a withdraw function in the ERC20TokenEmitter contract to transfer any leftover ether to the treasury/DAO.

Assessed type

ETH-Transfer

#0 - c4-pre-sort

2023-12-22T01:23:51Z

raymondfam marked the issue as sufficient quality report

#1 - c4-pre-sort

2023-12-22T01:24:04Z

raymondfam marked the issue as duplicate of #13

#2 - c4-pre-sort

2023-12-24T02:55:06Z

raymondfam marked the issue as duplicate of #406

#3 - c4-judge

2024-01-05T23:07:23Z

MarioPoneder marked the issue as satisfactory

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