During converting through pipelineConvert
, it is possible to have negative toStem
by manipulating the data when executeAdvancedFarmCalls
is called.
https://github.com/Cyfrin/2024-05-beanstalk-the-finale/blob/main/protocol/contracts/beanstalk/silo/PipelineConvertFacet.sol#L62
https://github.com/Cyfrin/2024-05-beanstalk-the-finale/blob/main/protocol/contracts/beanstalk/silo/PipelineConvertFacet.sol#L98
When converting X
amount of token bean to Y
LP tokens, during the function call executeAdvancedFarmCalls
, it is exepected that X
beans will be added as liquidity to the well, and Y
LP tokens are returned into the protocol. Regarding the grown stalks, the protocol calculates the amount of grown stalks associated to X
amount of beans, and then calculates the toStem
as if Y
LP tokens produced this amount of grown stalks. The formula for calculating toStem
is:
https://github.com/Cyfrin/2024-05-beanstalk-the-finale/blob/main/protocol/contracts/libraries/Convert/LibConvert.sol#L523
https://github.com/Cyfrin/2024-05-beanstalk-the-finale/blob/main/protocol/contracts/libraries/Silo/LibTokenSilo.sol#L551
The issue is that if during the function call executeAdvancedFarmCalls
, the bean amounts added as liquidity to the well is much less than X
, the returned LP tokens amount will be much less than Y
. But, the protocol still assumes that X
beans is converted so the grown stalks associated with X
beans will still be included in the calculations.
Thus, if stemTip < (grownstalks associated with X) / (equivalent bdv of small amount of LP tokens)
, the value of toStem
would be negative.
How to manipulate the amount of beans added to the liquidity in the well? In other words how to add small amount of beans as liquidity in the well instead of full X amount?
First X
beans are transferred to the C.PIPELINE
.
https://github.com/Cyfrin/2024-05-beanstalk-the-finale/blob/main/protocol/contracts/libraries/Convert/LibPipelineConvert.sol#L53
Second, executeAdvancedFarmCalls
is called that can execute the function advancedPipe
in the contract DepotFacet
.
https://github.com/Cyfrin/2024-05-beanstalk-the-finale/blob/main/protocol/contracts/beanstalk/farm/DepotFacet.sol#L51
This function can execute a series of calls (which are encoded by the user) through the function advancedPipe
in the contract Pipeline
.
https://github.com/Cyfrin/2024-05-beanstalk-the-finale/blob/main/protocol/contracts/pipeline/Pipeline.sol#L61
In this function, the malicious user could encode a function call to add small amount of beans as liquidity to the well instead of full X amounts. By doing so, small amount of LP tokens will be returned to the C.PIPELINE
.
The following foundry test shows that the attacker is going to convert 100e6
bean to LP, so the parameter amounts
is equal to [100e6]
. Thus, during the convert, 100e6
beans are transferred to the C.PIPELINE
. But, the created calls beanToLPFarmCalls
are as follows in order (Note that these encoded data are inserted as the parameter advancedFarmCalls
in the function pipelineConvert
):
transfer 100e6 - 10
to the attacker
approve max to the well
add 10
beans as liquidity to the well
By doing so, in reality, only 10
beans are added as liquidity to the well, and as a result 9
bdv of LP tokens are returned. But, since the grownstalks associated with 100e6
beans are considered for calculation of toStem
, we have: stemTip < (grownstalks associated with 100e6 beans) / (9)
. Thus, toStem
is negative value equal to -44444436444444
. Moreover, it shows that the deposit id is encoded pack of token address + uint96(toStem)
, since toStem
is negative, the uint96 type casting converts the toStem
to 0xffffffffffffd793f9274ae4
.
https://github.com/Cyfrin/2024-05-beanstalk-the-finale/blob/main/protocol/contracts/libraries/LibBytes.sol#L140
The output is:
Negative toStem
can have many impacts on the protocol during transfer deposits, withdrawing deposits, depositing enroots, and converting.
It means that the deposit is done in a negative cumulative grown stalks per bdv that does not make sense.
It is recomended to enforce to have non-negative toStem
when converting.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.