TransmuterBuffer's _alchemistWithdraw use hard coded slippage that can lead to user losses #127
Labels
2 (Med Risk)
Assets not at direct risk, but function/availability of the protocol could be impacted or leak value
bug
Something isn't working
sponsor acknowledged
Technically the issue is correct, but we're not going to resolve it for XYZ reasons
Lines of code
https://github.com/code-423n4/2022-05-alchemix/blob/de65c34c7b6e4e94662bf508e214dcbf327984f4/contracts-hardhat/TransmuterBuffer.sol#L511-L524
Vulnerability details
exchange() -> _exchange() -> _alchemistWithdraw() is user funds utilizing call sequence and the slippage hard coded to 1% there can cause a range of issues.
For example, if there is not enough shares, the number of shares to withdraw will be unconditionally reduced to the number of the shares available. This can pass under 1% slippage and user will give away up to 1% without giving a consent to such a fee, which is big enough to notice.
On the other hand, in a similar situation when there is not enough shares available a user might knowingly want to execute with even bigger fee, but hard coded slippage will not be met and the withdraw be unavailable and funds frozen.
Setting the severity to medium as the end impact is either modest user fund loss or exchange functionality unavailability.
Proof of Concept
_alchemistWithdraw uses hard coded 1% slippage threshold and rewrites wantShares to be availableShares once TransmuterBuffer's position isn't big enough:
https://github.com/code-423n4/2022-05-alchemix/blob/de65c34c7b6e4e94662bf508e214dcbf327984f4/contracts-hardhat/TransmuterBuffer.sol#L511-L524
Alchemist's _unwrap will revert withdrawUnderlying call once minimumAmountOut isn't met:
https://github.com/code-423n4/2022-05-alchemix/blob/de65c34c7b6e4e94662bf508e214dcbf327984f4/contracts-full/AlchemistV2.sol#L1344-L1346
There are 2 use cases for the function:
exchange (onlyKeeper) -> _exchange -> _alchemistWithdraw,
setFlowRate (onlyAdmin) -> _exchange -> _alchemistWithdraw
exchange() is the most crucial as it should be able to fulfil various types of user funds exchange requests:
https://github.com/code-423n4/2022-05-alchemix/blob/de65c34c7b6e4e94662bf508e214dcbf327984f4/contracts-full/TransmuterBuffer.sol#L526-L546
This way, one issue here is that user can end up giving away the full 1% unconditionally to market situation because there are not enough shares available.
Another one is that knowing that the conditions are bad or that there are not enough shares available and willing to run the exchange with bigger slippage the user will not be able to as there are no means to control it and the functionality will end up unavailable, being reverted by Alchemist's _unwrap check.
Recommended Mitigation Steps
Consider adding the function argument with a default value of 1%, so the slippage can be tuned when it is needed.
The text was updated successfully, but these errors were encountered: