Skip to content
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

Gas Coin Setup Result In Immediate Profitable Arbitrage #580

Open
c4-bot-1 opened this issue Dec 18, 2023 · 13 comments
Open

Gas Coin Setup Result In Immediate Profitable Arbitrage #580

c4-bot-1 opened this issue Dec 18, 2023 · 13 comments
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 downgraded by judge Judge downgraded the risk level of this issue insufficient quality report This report is not of sufficient quality M-01 satisfactory satisfies C4 submission criteria; eligible for awards selected for report This submission will be included/highlighted in the audit report sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")

Comments

@c4-bot-1
Copy link
Contributor

Lines of code

https://github.com/zeta-chain/node/blob/main/x/fungible/keeper/msg_server_deploy_fungible_coin_zrc20.go#L34

Vulnerability details

Impact

A gas coin can be added by running the DeployFungibleCoinZRC20 message. This is most notably done when adding a new blockchain support, because each of them has their respective supported “gas ZRC20” which is the native token of this newly supported blockchain as a ZRC compliant token on Zetachain. These liquidity pools are required because we need to be able to get those “gas ZRC20” at some point in order to burn them to redeem them for an equivalent amount of native tokens.

If this new blockchain that is supported is Polygon, then we will deploy a liquidity pool with 0.1 WZETA and 0.1 zrc20-MATIC on deployment so validators can swap these ZETA tokens for the Polygon’s native token.

From the code:

// If this is a gas coin, the following happens:
//
// * ZRC20 contract for the coin is deployed
// * contract address of ZRC20 is set as a token address in the system
// contract
// * ZETA tokens are minted and deposited into the module account
// * setGasZetaPool is called on the system contract to add the information
// about the pool to the system contract
// * addLiquidityETH is called to add liquidity to the pool

Which calls the SetupChainGasCoinAndPool function.

This is not an issue for low value tokens, but is for tokens such as BTC, ETH, and SOL.
If we take the example of BTC, with 0.1 BTC having a value of ~4400$ being added with a ZETA token which is going to make the pool imbalanced with a significant value at stake.

An arbitrage opportunity will be created as a first come first serve rule, which is going to be a net loss for the protocol because these “gas ZRC20” can be directly redeemed for native tokens on the blockchain by users by withdrawing the assets later.

Someone could then monitor for new blockchains supported by Zetachain and if the token valuation is extremely disparate compared to the ZETA token, they could backrun the liquidity add by swapping some ZETA tokens and make an instant profit.

In this command, we ask for the token0 name of the pair 0 which is the ETH ZRC20 gas token

$ cast call $(cast call $(cast call 0x9fd96203f7b22bCF72d9DCb40ff98302376cE09c "allPairs(uint256)(address)" 0) "token0()(address)") "name()(string)"
"ETH-goerli_localnet"

And we can also verify that the balance of each assets in the reserves is 0.1

$ cast call $(cast call 0x9fd96203f7b22bCF72d9DCb40ff98302376cE09c "allPairs(uint256)(address)" 0) "getReserves()(uint112,uint112,uint32)"
100000000000000000 [1e17]
100000000000000000 [1e17]
1702765357 [1.702e9]

Next, let’s check for BTC

$ cast call $(cast call $(cast call 0x9fd96203f7b22bCF72d9DCb40ff98302376cE09c "allPairs(uint256)(address)" 1) "token1()(address)") "name()(string)"
"BTC-btc_regtest"

Make sure that 0.1 BTC is in the reserves

$ cast call $(cast call 0x9fd96203f7b22bCF72d9DCb40ff98302376cE09c "allPairs(uint256)(address)" 1) "getReserves()(uint112,uint112,uint32)"
100000000000000000 [1e17]
10000000 [1e7]
1702765357 [1.702e9]

Tools Used

Manual

Recommended Mitigation Steps

Before adding a new blockchain and a gas token, you could either add much less initial liquidity such as a mantissa of -3 to make the BTC amount much less profitable, or make the initial liquidity configurable from the message passing.

Assessed type

MEV

@c4-bot-1 c4-bot-1 added 3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working labels Dec 18, 2023
c4-bot-1 added a commit that referenced this issue Dec 18, 2023
@DadeKuma
Copy link

Assumes admin error

@c4-pre-sort c4-pre-sort added the insufficient quality report This report is not of sufficient quality label Dec 20, 2023
@c4-pre-sort
Copy link

DadeKuma marked the issue as insufficient quality report

@0xean
Copy link

0xean commented Jan 5, 2024

Assumes admin error

Can you explain this a bit more?

@DadeKuma
Copy link

DadeKuma commented Jan 6, 2024

@0xean Re-reading this, it might be a mistake on my part; my initial thought was that SetupChainGasCoinAndPool has a FIXME comment so the logic was incomplete, but now I see that the FIXME refers only to the cointype/gas limit issue.

As such, it seems that the final intention is to hardcode the liquidity.

@0xean
Copy link

0xean commented Jan 6, 2024

okay, thanks. I think this is probably not a huge impact / small leak of value, but still worth having the sponsor comment to make sure we aren't missing something.

@0xean
Copy link

0xean commented Jan 7, 2024

@c4-sponsor

@c4-sponsor c4-sponsor added the sponsor disputed Sponsor cannot duplicate the issue, or otherwise disagrees this is an issue label Jan 9, 2024
@c4-sponsor
Copy link

lumtis (sponsor) disputed

@c4-sponsor
Copy link

lumtis marked the issue as disagree with severity

@c4-sponsor c4-sponsor added the disagree with severity Sponsor confirms validity, but disagrees with warden’s risk assessment (sponsor explain in comments) label Jan 9, 2024
@c4-sponsor
Copy link

lumtis (sponsor) confirmed

@c4-sponsor c4-sponsor added sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity") and removed sponsor disputed Sponsor cannot duplicate the issue, or otherwise disagrees this is an issue labels Jan 9, 2024
@c4-sponsor
Copy link

lumtis marked the issue as agree with severity

@c4-sponsor c4-sponsor removed the disagree with severity Sponsor confirms validity, but disagrees with warden’s risk assessment (sponsor explain in comments) label Jan 9, 2024
@c4-judge c4-judge removed the 3 (High Risk) Assets can be stolen/lost/compromised directly label Jan 9, 2024
@c4-judge
Copy link

c4-judge commented Jan 9, 2024

0xean changed the severity to 2 (Med Risk)

@c4-judge c4-judge added 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value downgraded by judge Judge downgraded the risk level of this issue labels Jan 9, 2024
@c4-judge
Copy link

c4-judge commented Jan 9, 2024

0xean marked the issue as satisfactory

@c4-judge c4-judge added the satisfactory satisfies C4 submission criteria; eligible for awards label Jan 9, 2024
@c4-judge
Copy link

0xean marked the issue as selected for report

@c4-judge c4-judge added the selected for report This submission will be included/highlighted in the audit report label Jan 11, 2024
@C4-Staff C4-Staff added the M-01 label Jan 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
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 downgraded by judge Judge downgraded the risk level of this issue insufficient quality report This report is not of sufficient quality M-01 satisfactory satisfies C4 submission criteria; eligible for awards selected for report This submission will be included/highlighted in the audit report sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")
Projects
None yet
Development

No branches or pull requests

7 participants