-
Notifications
You must be signed in to change notification settings - Fork 3
Description
The join functionality can be broken
Summary
An attacker can prevent users from joining a DAO.
The incentive could be to block new users from voting on a proposal.
Risk Rating
4
Vulnerability Details
The ElasticDAO.join function requires the exact amount of ETH (msg.value) to be sent for the desired shares:
function join(uint256 _deltaLambda)
external
payable
onlyAfterSummoning
onlyWhenOpen
preventReentry
{
// ...
if (deltaE != msg.value) {
revert('ElasticDAO: Incorrect ETH amount');
}
}An attacker can observe the mempool for any join transactions and send a tiny amount of wei to the DAO contract. This changes the capitalDelta computation which, in return, changes the deltaE computation to a different value than the one calculated by a user at the time they tried to join the DAO.
uint256 capitalDelta =
ElasticMath.capitalDelta(
// the current totalBalance of the DAO is inclusive of msg.value,
// capitalDelta is to be calculated without the msg.value
// CAN SEND TINY AMOUNT OF WEI AND CHANGE THIS
address(this).balance - msg.value,
tokenContract.totalSupply()
);
uint256 deltaE =
ElasticMath.deltaE(
_deltaLambda,
capitalDelta,
token.k,
token.elasticity,
token.lambda,
token.m
);This can also happen naturally from normal DAO usage whenever any of the token curve parameters change.
Impact
Users can be blocked from joining a DAO.
Proof of Concept
Tools Used
Recommended Mitigation Steps
Consider checking msg.value >= deltaE and sending back the remaining amount.
This is similar to a slippage parameter on AMMs.
This drastically increases the economic costs of such a join frontrunning attack.
Definition of Done
- Join succeeds when
msg.value >= deltaE - There is a test showing join succeeding when msg.value is > deltaE