When poolSharesToken total supply is zero an attacker goes ahead and executes the following steps :
Deposit a few assets in LenderCommitmentGroup_Smart.sol using addPrincipalToCommitmentGroup()
Then Attacker creates a Borrow position using SCF contract.
Then wait for a block, In 12 seconds when atleast 1 wei of interest has accurred, repay all the borrowed funds and interest.
After this they redeem all but 1 wei of shares.
This makes it so that the poolSharesToken = 1 and poolTotalEstimatedValue_ >= 2 due to rounding.
Now attacker takes advantage of rounding down when depositing to inflate the price of a share.
In a loop attacker does the following till they get their desired price of 1 share
deposit 2*(poolTotalEstimatedValue - 1 )assets
According to (amount * EXCHANGE_RATE_EXPANSION_FACTOR) / rate . ( rate = poolTotalEstimatedValue *
EXCHANGE_RATE_EXPANSION_FACTOR) /
poolSharesToken.totalSupply()`)
it mints shares = (2poolTotalEstimatedValue - 1 totalShares) /poolTotalEstimatedValue; of shares.
Since the attacker has deposited 2poolTotalEstimatedValue - 1 assets and totalShares is 1, shares = (2
(poolTotalEstimatedValue - 1) * 1) / poolTotalEstimatedValue = 1 is minted.
This should have been 1.9999... but due to rounding down, the attacker gets minted 1 shares.
This means at this point totalShares = 1+1 = 2 and poolTotalEstimatedValue = poolTotalEstimatedValue + 2*
(poolTotalEstimatedValue - 1.
After this attacker would burn 1 share using burnSharesToWithdrawEarnings().
So now totalShares= 1 and poolTotalEstimatedValue = 2*poolTotalEstimatedValue - 1
In this loop the supply stays (totalShares) at 1 and poolTotalEstimatedValue increase exponentially.
Impact
This attack has two implications: Implicit minimum Amount and funds lost due to rounding errors
If an attacker is successful in making 1 share worth z assets and a user tries to mint shares using k*z assets then,
If k<1, then the user gets zero share and they loose all of their tokens to the attacker
If k>1, then users still get some shares but they lose (k- floor(k)) * z) of assets which get proportionally divided between existing
share holders (including the attacker) due to rounding errors.
This means that for users to not lose value, they have to make sure that k is an integer.
smbv-1923
high
Share Inflation Attack via Internal Accounting
Summary
Vulnerability Detail
poolSharesToken
total supply is zero an attacker goes ahead and executes the following steps :LenderCommitmentGroup_Smart.sol
usingaddPrincipalToCommitmentGroup()
poolSharesToken
= 1 andpoolTotalEstimatedValue_
>= 2 due to rounding.(amount * EXCHANGE_RATE_EXPANSION_FACTOR) / rate
. ( rate = poolTotalEstimatedValue * EXCHANGE_RATE_EXPANSION_FACTOR) / poolSharesToken.totalSupply()`)burnSharesToWithdrawEarnings()
.Impact
Code Snippet
https://github.com/sherlock-audit/2024-04-teller-finance/blob/main/teller-protocol-v2-audit-2024/packages/contracts/contracts/LenderCommitmentForwarder/extensions/LenderCommitmentGroup/LenderCommitmentGroup_Smart.sol#L262 https://github.com/sherlock-audit/2024-04-teller-finance/blob/main/teller-protocol-v2-audit-2024/packages/contracts/contracts/LenderCommitmentForwarder/extensions/LenderCommitmentGroup/LenderCommitmentGroup_Smart.sol#L307 https://github.com/sherlock-audit/2024-04-teller-finance/blob/main/teller-protocol-v2-audit-2024/packages/contracts/contracts/LenderCommitmentForwarder/extensions/LenderCommitmentGroup/LenderCommitmentGroup_Smart.sol#L324
Tool used
Manual Review
Recommendation
Mint 10**3 of poolSharesToken to dead address.
Duplicate of #64