DeFiHardhat
21,000 USDC
View results
Submission Details
Severity: high
Invalid

Attacker can yet exploit inflated BDV to earn more beans

Vulnerability Details

When a user deposits in the Silo, the number of Stalk associated with that deposited is based on the bdv.

// LibTokenSilo.deposit
uint256 bdv = beanDenominatedValue(token, amount);
return depositWithBDV(account, token, stem, amount, bdv);
// TokenSilo._deposit
@> (stalk, germ) = LibTokenSilo.deposit(
account,
token,
stem = LibTokenSilo.stemTipForToken(token),
amount
);
@> LibSilo.mintGerminatingStalk(account, uint128(stalk), germ);

Given the user has mown and he got Active Stalk, he is now able to earn beans when calling plant from SiloFacet.

function _plant(address account) internal returns (uint256 beans, int96 stemTip) {
// Need to Mow for `account` before we calculate the balance of
// Earned Beans.
LibSilo._mow(account, C.BEAN);
@> uint256 accountStalk = s.a[account].s.stalk; // @audit calculated using inflated bdv
// Calculate balance of Earned Beans.
@> beans = LibSilo._balanceOfEarnedBeans(accountStalk, s.a[account].roots); // @audit inflated beans due to inflated accountStalk->bdv
stemTip = LibTokenSilo.stemTipForToken(C.BEAN);
if (beans == 0) return (0, stemTip);
// Reduce the Silo's supply of Earned Beans.
// SafeCast unnecessary because beans is <= s.earnedBeans.
s.earnedBeans = s.earnedBeans.sub(uint128(beans));
// Deposit Earned Beans if there are any. Note that 1 Bean = 1 BDV.
LibTokenSilo.addDepositToAccount(
account,
C.BEAN,
stemTip,
@> beans, // amount
@> beans, // bdv
LibTokenSilo.Transfer.emitTransferSingle
);

There are several ways that the attacker can yet exploit the system using the inflated BDV. The anti-lambda function will not prevent this.

Exploit scenarios:

  • (A) the attacker has a large BDV position and is watching the mempool for transactions to update his BDV, he front-runs the convert anti-lambda transaction and calls the plant function from `SiloFacet, hence he earns beans based on the inflated BDV.

  • (B) the attacker fronts-run the anti-lambda call and convert his assets into another (i.e Beans). Given that the convert function will consider the greater BDV, the attacker will yet keep it inflated.

  • (C) the attacker creates several deposits from several accounts on Silo, i.e. 300 accounts with 300 deposits. As the accounts have very small deposits and the gas fees on Ethereum are pricy, users will not be incentivized to decrease the BDV of those accounts when the market goes down. While the market is going down substantially, the attacker uses the inflated BDV to earn overpaid Grown Stalk and Beans over time. The attacker keeps planting Stalk to earn more beans over time.

  • (D) The Attacker makes several deposits with different depositIds into one account, he applies the same strategy as scenario (A) and transfers the deposit to another account so he doesn't have his deposit converted by the anti-lambda call.

Impact

  • Anti-lambda convert doesn't actually protect the protocol and silo deposits from inflated BDV when it is front-runed.

  • Small positions have a high chance of not having the BDV updated to gas price.

  • Protocol will keep overissuing Grown Stalks and Beans for the attackers while the market is going down.

  • In a transition to a bear market, the protocol will enter into bad debt and have the bean's price depreciated heavily.

Tools Used

Manual Review

Recommendations

  • Consider using a time limit(against the last interaction) for all the interactions with the SiloFacet. Once this time limit is reached, the account must pass on the "BDV healthy" check and then apply the convert anti-lambda to update the user's BDV to the correct value. i.e modifier updateBdvIfNeeded().

  • Think about covering other cases like the Silo transfer(as the transfer carries all the Deposit assets with it). This will prevent users from front-running the convert call and transferring their assets to another account to escape from the decreased BDV.

  • (Additional) Consider other strategies(i.e. cooldown) to prevent the inflated BDV from being used on the SiloFacet.

Updates

Lead Judging Commences

giovannidisiena Lead Judge
about 1 year ago
giovannidisiena Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Out of scope
holydevoti0n Submitter
about 1 year ago
holydevoti0n Submitter
about 1 year ago
giovannidisiena Lead Judge
about 1 year ago
holydevoti0n Submitter
about 1 year ago
holydevoti0n Submitter
about 1 year ago
giovannidisiena Lead Judge
about 1 year ago
holydevoti0n Submitter
about 1 year ago
giovannidisiena Lead Judge
about 1 year ago
holydevoti0n Submitter
about 1 year ago
giovannidisiena Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Out of scope

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.