-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
coinswap
liquidity pool susceptible to inflation attacks
#13
Comments
|
Hi @poorphd, my understanding is that a "donation for inflation" attack is an effective way to prevent legitimate liquidity providers away from the pool (or let them in at the price of losing tokens to massive rounding). However, I am not sure I fully understand this part of your reply:
Can you please explain more about this so I have a full picture for judging this group? Thanks! |
Hi @3docSec, On Canto, the coinswap pool is used to automatically swap a portion of the assets transferred via IBC for onboarding users. Only a minimum amount of liquidity is provided for this feature, and the max size of the pool is also set. https://canto-api.synergynodes.com/canto/coinswap/params {
"params": {
"fee": "0.000000000000000000",
"pool_creation_fee": {
"denom": "stake",
"amount": "0"
},
"tax_rate": "0.000000000000000000",
"max_standard_coin_per_pool": "10000000000000000000000",
"max_swap_amount": [
{
"denom": "ibc/17CD484EE7D9723B847D95015FA3EBD1572FD13BC84FB838F55B18A57450F25B",
"amount": "10000000"
},
{
"denom": "ibc/4F6A2DEFEA52CD8D90966ADCB2BD0593D3993AB0DF7F6AEB3EFD6167D79237B0",
"amount": "10000000"
},
{
"denom": "ibc/DC186CA7A8C009B43774EBDC825C935CABA9743504CE6037507E6E5CCE12858A",
"amount": "10000000000000000"
}
]
}
}
params := k.GetParams(ctx)
if !params.MaxSwapAmount.AmountOf(msg.MaxToken.Denom).IsPositive() {
return sdk.Coin{}, errorsmod.Wrapf(types.ErrInvalidDenom,
"MaxToken %s is not registered in max swap amount", msg.MaxToken.Denom)
} Anyone can create a pool, but only pools for the IBC voucher set in the parameter can be created. Currently, Canto has only 3 IBC vouchers whitelisted, and the foundation has already created 3 pools for these vouchers at max size (maximum liquidity of the pool). Therefore, the probability of the attack scenario raised in the issue occurring is very low as you would have to donate a very large amount for the “donation for inflation”. |
Ok thanks for the clarification. In my opinion, there is the possibility to backrun an upgrade or governance proposal to add a new MaxToken, but this can be mitigated by the fact that x/governance proposals like the TextProposal are multi-message, so the team has the tools to atomically add a max token and provide liquidity for its pool at cap. Adding #7 and #26 to this pool as they are different nuances of the same root cause (donation for inflation). Marking the whole group as QA because:
|
3docSec changed the severity to QA (Quality Assurance) |
3docSec marked the issue as grade-b |
Lines of code
https://github.com/code-423n4/2024-05-canto/blob/d1d51b2293d4689f467b8b1c82bba84f8f7ea008/canto-main/x/coinswap/keeper/keeper.go#L149-L192
Vulnerability details
Impact
The
coinswap
module implements a constant product AMM enabling users to swap between the standard token and nay other token. However, just like other constant product AMMs, thecoinswap
module is susceptible to inflation attacks.The protocol does not implement a minimum liquidity addition amount. So a user can add as little liquidity as they want, even a single wei of each token.
Due to the missing check in the above snippet, a user can open a pool with 1 wei
standard
and 1 weitoken
and mint out 1 wei of LP token. Then when the protocol is calculating the balances, it uses the raw balances.So the malicious user can donate standard or token amounts externally to the escrow address, and that will change the liquidity in the pool. Say the user donates 1e18 standard and tokens to the pool escrow. The pool will now have 1e18+1 standard and 1e18+1 tokenin the escroe.
When other users try to deposit further liquidity, they will be faced with this steep price. If they deposit 1e18 tokens + 1e18 standard, their Lp will be calculated in the following way.
Since
liquidity=1
from the last step andmaxStandardInputAmt=1e18
andstandardReserveAmt=1e18+1
, there will be a rounding error and themintLiquidityAmt
will be calculated as 0.Depositors can prevent this with setting slippage with
msg.MinLiquidity
, but even a single wei difference will lead to a large loss of funds, and the slippage will always revert if provided. So there will either be a DOS of the pool, or losses by the depositor.So the earliest depositor can either block the pool with a DOS or steal funds from later depositors. Thus this is a medium severity issue.
Proof of Concept
Say Alice mints out 1 wei of liquidity, by depositing 1 wei
standard
and 1 weitoken
. Since there is no minimum mint amount, this is allowed.Alice then transfers to the contract 1e18
standard
and1e18
token
. The pool will now have 1e18+1 standard and 1e18+1 token in the escrow.Bob comes and tries to deposit 1e18
standard
and 1e18token
to the pool. Bob's liquidity amount will be calculated as1*1e18/(1e18+1) = 0
. Thus Bob either loses their deposit, or cannot participate at all.Tools Used
Manual Review
Recommended Mitigation Steps
Burn the initial 1000 wei of liquidity minted, like is done in uniswap v2 pools.
Assessed type
Math
The text was updated successfully, but these errors were encountered: