Incentive Pool can be drained without rebalancing the pool #87
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 confirmed
Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")
Lines of code
https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/LiquidityPool.sol#L149-L173
https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/LiquidityPool.sol#L263-L277
Vulnerability details
Impact
depositErc20
allows an attacker to specify the destination chain to be the same as the source chain and the receiver account to be the same as the caller account. This enables an attacker to drain the incentive pool without rebalancing the pool back to the equilibrium state.Proof of Concept
This requires the attacker to have some collateral, to begin with. The profit also depends on how much the attacker has. Assume the attacker has enough assets.
In each chain, when the pool is very deficit (e.g.
currentLiquidity
is much less thanprovidedLiquidity
), which often mean there's a good amount in the Incentive pool after some high valued transfers, then do the following.depositErc20()
withtoChainId
being the same chain andreceiver
beingmsg.sender
.The executor will call
sendFundsToUser
to msg.sender. Then a rewardAmount, equivalent to the entire incentive pool (up to 10% of the total pool value), will be added tomsg.sender
minus equilibrium fee (~0.01%) and gas fee.In the end, the pool is back to the deficit state as before, the incentive pool is drained and the exploiter pockets the difference of rewardAmount minus fees.
This attack can be repeated on each deployed chain multiple times whenever the incentive pool is profitable (particularly right after a big transfer).
Tools Used
Recommended Mitigation Steps
Disallow
toChainId
to be the source chain by validating it indepositErc20
or insendFundsToUser
validate thatfromChainId
is not the same as current chain.require
receiver
is notmsg.sender
indepositErc20
.The text was updated successfully, but these errors were encountered: