Open c4-bot-10 opened 11 months ago
Possible divergence from whitepaper, probably QA
DadeKuma marked the issue as insufficient quality report
0xean changed the severity to QA (Quality Assurance)
0xean marked the issue as grade-a
My report is exposing a clear divergence with the ZetaChain whitepaper and the implementation (ccing: @lumtis as I don't think he saw the report since classified as insufficient quality report
and should be aware). The fact that this security mechanism
is taking up an entire section in their whitepaper, but more importantly that it is supposed to protect all the ZETA holders of a potential bug that would allow to invalid mint of ZETA, combined with the fact that the code in their smart contract as shown in my PoC is kind of weak (see Supply check in connector contract is weak
), all this combined seems to warrant at least Medium
severity.
Why does this matter?
The negative impact explained in the whitepaper would be possible: an unknown vulnaribility being exploited to allow invalid minting that inflates the total supply of ZETA across chains
. MintZetaToEVMAccount which is used here is the central point to minting ZETA and is not connected at all with the ZetaSupplyChecker::ValidateZetaSupply
, which seems to be the only piece of logic in the ZetaChain node that do some sort of calculation in that regards. Furthermore, the whitepaper claim that The total supply of ZETA is provided by Chainlink and posted on each connected chain
, which seems innacurate, at least I could not find any code that is doing such thing. Again, only ZetaSupplyChecker seems to be implemented in the moment, but is acting in a silo and as a passive tool.
For all the mention above, I would ask @0xean to reconsider this issue to be upgraded to Medium
and unique
finding and I would also appreciate the feedback of the sponsor @lumtis on the report. I saw multiple contest in 2023 where documentation divergence with implementation did warrant Medium and this seems to be one of them, it's not a simple bleep on the radar, it's an important security mecanism for the ZetaChain which is not walking the talk.
https://docs.code4rena.com/awarding/judging-criteria/severity-categorization#estimating-risk
If you want to argue severity you need to do within the framework. I will welcome one last comment on the topic, but tagging in the sponsor hoping for a different response doesn't help your case. A fact based response if welcomed, but arguing they should remove a section of the white paper is definitely QA. Your report shows potential "weaknesses" but no clear exploit.
Lines of code
https://github.com/code-423n4/2023-11-zetachain/blob/main/repos/node/zetaclient/zeta_supply_checker.go#L113-L116 https://github.com/code-423n4/2023-11-zetachain/blob/main/repos/protocol-contracts/contracts/evm/ZetaConnector.non-eth.sol#L16 https://github.com/code-423n4/2023-11-zetachain/blob/main/repos/protocol-contracts/contracts/evm/ZetaConnector.non-eth.sol#L69
Vulnerability details
Description
The whitepaper claim at
section 7.3
that the protocol implement adefense mechanism
to prevent ZETA token to be inflated with invalid mint, such that the total supply cannot be inflated in case of bugs being exploited.However, such mechanism is currently
only partially implemented
which seems to warrantMedium
severity.Impact
Documentation claim is inaccurate and the Zeta platform cannot claim to have such
Comprehensive Defense Against Arbitrary Minting
mechanism in place in the moment.Proof of Concept
I would like to describe in more details what are the current weakness of the defense mechanism.
ZetaSupplyChecker could potentially cause Observer to panic and also erroneous calculate the totalspply
, ZetaSupplyChecker:passive
in the moment asCheckZetaTokenSupply
is only printing a log in case of error andValidateZetaSupply
return value (so if totalSupply is good or not) is not even consummed.Supply check in connector contract is weak.
ZetaConnectorNonEth::onReceive
is only checking against the totalSupply of the current external chain, not accounting for all the other supply available on other chains (which ZetaSupplyChecker try todo)maxSupply
is initialized withmaxSupply = 2 ** 256 - 1;
maximum uint256 value at contract deployment, and might not be set to a lower value later on (using setMaxSupply, and what would be this magic value?), which make this check useless if the maxSupply has not be overwritten afterwards. And I just checked on now (December 8th, 11h41 UTC-5) the Mumbai's connector, and confirm that this is the case in the moment, maxSupply has not been overwritten yet (so still at115792089237316195423570985008687907853269984665640564039457584007913129639935
, which expose this flaw.Recommended Mitigation Steps
Remove such claim from the WhitePaper or complete the mechanism such that it work as described. If you want to complete it, I would suggest the following steps:
ZetaSupplyChecker
.ZetaConnectorNonEth.sol
. I would remove the maxSupply logic from the connector contract as a whole, right now it doesn't bring any value, and put all this inside the Observer code logic, such that before callingonReceive
(SignOutboundTx) oronRevert
(SignRevertTx), you add a check that communicate withZetaSupplyChecker
to see if this new supply can be minted, as this is the only place where you have the full picture of the totalsupply.Assessed type
Error