-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Steal NFTs from a Vault, and ETH + Fractional tokens from users. #27
Labels
3 (High Risk)
Assets can be stolen/lost/compromised directly
bug
Warden finding
sponsor confirmed
Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")
Comments
code423n4
added
3 (High Risk)
Assets can be stolen/lost/compromised directly
bug
Warden finding
labels
Jul 8, 2022
Ferret-san
added
the
sponsor confirmed
Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")
label
Jul 20, 2022
This was referenced Jul 20, 2022
This was referenced Jul 20, 2022
Closed
Closed
This was referenced Jul 20, 2022
This was referenced Jul 21, 2022
This is a very detailed report! Agree this is a High risk finding. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
3 (High Risk)
Assets can be stolen/lost/compromised directly
bug
Warden finding
sponsor confirmed
Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")
Lines of code
https://github.com/code-423n4/2022-07-fractional/blob/e2c5a962a94106f9495eb96769d7f60f7d5b14c9/src/modules/Migration.sol#L292
Vulnerability details
Impact
Steal NFTs from a Vault, and ETH + Fractional tokens from users.
Description
The
Migration.sol
module expects users to join a proposal using thejoin
function, and leave a proposal using theleave
function, both functions update fraction and ether balances of the proposal and the caller.The
withdrawContribution
function is meant to be used to retrieve ether and fractions deposited from an unsuccessful migration, but it can be called as well in proposals that have not been commited.Unfortunately, the
withdrawContribution
function will issue a refund on fraction tokens and ether balances the user sent to a proposal but it will not update the variablestotalEth
andtotalFractions
(asjoin
andleave
do), leading to an inflation of ETH and fractional tokens if the user callsjoin
,withdrawContribution
andjoin
again.Exploiting this inflation bug, an attacker can steal all Ether and fractional tokens sent to a legit proposal by legit users of the community, and redirect them to an evil proposal that will win (because it has over 51% of token supply) and at the same time invalidate the legit proposal due to:
1- Lack of funds (they were stolen).
2- Only 1 LIVE proposal can be running at the same time.
A key element to take note is that only 1 proposal can be
LIVE
, but before a proposal goesLIVE
, many can be created at the same time, and users can join those that resonate with them, sending their ETH and fractional tokens to support it. The vault will have a big amount of ETH and fractional tokens in these situations.Steps to reproduce
An attacker's will exploit the inflation bug as follow:
1- Wait until there's at least 50% of the total supply of fractional tokens in the vault, being stacked into one or several proposals.
2- Create an evil proposal with evil modules and inflate the amount of ETH and fractional tokens in your proposal up to the exact amount of the total ETH and fractional tokens in the vault.
3- Commit your proposal. That will send all ETH and fractional tokens in the vault to your proposal and
start
it.Now that your proposal has over 51% total supply of fractional tokens in it and a lot of ETH stolen from members of the vault, many creative things can be done, including taking over the Vault's NFTs with an evil module once the proposal goes through.
**NOTE: In the
REJECTION_PERIOD
victims can buy tokens to try to stop the proposal from going through, but the price of every tokens is calculated using thedepositAmount
andmsg.value
(https://github.com/code-423n4/2022-07-fractional/blob/e2c5a962a94106f9495eb96769d7f60f7d5b14c9/src/modules/Buyout.sol#L86) both values manipulated by the attacker. **Proof of Concept
The proof of concept took 4 hours and 33 mins to be written, as I tried hard to get a clean, and easy to understand and reproduce PoC that illustrates the impact of the attack.
Everything was put inside a function filled with comments at every stage, that can be included within the Unit Tests of the project.
You can read the PoC or include the function in
test/Migration.t.sol
and callforge test -vvv --match-test testProposalAttack
to execute it.Tools Used
Run
forge test -vvv --match-test testProposalAttack
after preparing the testing environment as explained in https://github.com/code-423n4/2022-07-fractional#prepare-environmentRecommended Mitigation Steps
Update the
proposal.totalEth
andproposal.totalFractions
in thewithdrawContribution
function.The text was updated successfully, but these errors were encountered: