Open hats-bug-reporter[bot] opened 1 year ago
Hi @tsudmi, while this issue has a similar impact to #109, it is fundamentally different.
You can see this in the attack scenarios given: the example in #109 uses 100% LTV with 1% liquidation premium, while this issue uses 103% LTV with 0% liquidation premium.
Hi @MiloTruck , I think the situation here is similar. We won't remove the liquidation premium, so it will be above 0%. The liquidations will most probably be executed by MEV bots.
Github username: @milotruck Submission hash (on-chain): 0xa2b2b9cfac0e8a5b2bb559c1ee365019a2d990b149d46c7711f76267701e2b49 Severity: medium
Description:
Bug Description
In
VaultOsToken.sol
, whenliquidateOsToken()
is called to liquidate a staker, the following occurs:osTokenShares
:VaultOsToken.sol#L187-L193
osTokenShares
is subtracted from the staker's osETH position:VaultOsToken.sol#L224-L226
VaultOsToken.sol#L228
VaultOsToken.sol#L235-L236
VaultOsToken.sol#L247-L248
As seen from above, the amount of assets liquidated is determined using the osETH exchange rate. Additionally, since the entire liquidated amount and premium is transferred to the caller, the liquidation penalty is only reflected in
position.shares
.This becomes an issue if:
as he is incentivised to fully liquidate himself instead of burning osETH using
burnOsToken()
. This way, the staker only needs to use a portion of his osETH balance to withdraw all his staked ETH.Attack Scenario
For convenience, we assume that:
osToken
contract and a vault is 1.liqBonusPercent
is set to10_000
.Assume that Alice has the following osETH position in a vault:
32e18
shares, which corresponds to 32 ETH staked.28.8e18
osETH, which corresponds to 28.8 ETH worth of osETH.The vault experiences a loss of 4 ETH:
Alice wants to fully exit her position and withdraw all her staked ETH. If she calls
burnOsToken()
to burn all her shares andredeem()
afterwards:burnOsToken()
with all her osETH, asposition.shares
must be 0 for a staker to withdraw his entire balance.redeem()
burns32e18
shares and transfers 28 ETH to Alice.However, if she liquidates her own position, she gets to keep a portion of her osETH:
liquidateOsToken()
withosTokenShares = 28e18
:position.shares = 28.8e18 - 28e18 = 0.8e18
receivedAssets = 28e18
Although
position.shares
is non-zero, Alice has managed to withdraw all her staked ETH by self-liquidating. By doing so, she also gained an additional0.8e18
osETH.Impact
By self-liquidating, stakers can gain additional osETH when exiting positions with greater than 100% LTV ratios. The additional osETH is accrued as bad debt for the protocol, which could accumulate and destabilize the osETH peg in the long term.
Recommended Mitigation
Consider charging an additional liquidation fee, which is taken from the staker and given to the protocol. This would discourage self-liquidation as the staker does not get all his staked ETH in return when liquidating his own position.