xSNXa False Start: Post Mortem
Earlier in the week, we had to enact an emergency shutdown of xSNXa, owing to a potential exploit identified by security researcher samczsun. This was a disappointment to all of us — especially less than 24 hours after launch — but we are fortunate that all funds are safe and redeemable. As of this publication, the vast majority of holders have redeemed their xSNXa and we encourage those who haven’t to do so when possible (although nothing is urgent).
We’ll be launching a new instance of xSNXa in the coming weeks with the necessary changes to the code and after another security review.
- 12:13 PM EST: samczsun reaches out via Twitter DM
- 12:27 PM EST: We connect with Sam on Telegram. Over the next few minutes, Sam explains the potential exploit and Georgios Konstantopolous validates the existence of a vulnerability. We reach out to the Synthetix team to inform them of the vulnerability.
- 12:42 PM EST: We pause minting on xSNXa. Over the next 20 minutes, we liquidate SNX holdings into ETH over five transactions using the admin unwind function. (The contract only offers redemptions in ETH due to the mechanics of SNX staking, so the liquidation protocol requires exchanging into ETH.)
- There are still 8400 SNX that are unable to be unlocked until 9:34 PM EST, due to limitations on burning debt in the Synthetix ecosystem. We determine that the likelihood of these funds being at risk is minimal and that it would be best to begin informing the community. Some users have begun to notice that minting xSNXa is disabled on the xToken UI.
- 3:55 PM EST: We begin to inform the community, first in the xToken and Synthetix Discords and then shortly after on Twitter.
- 9:34 PM EST: Over the course of the next half hour, we safely unlock all remaining SNX. We transfer $1891 of sUSD into the xSNXa contract in order to burn all remaining debt. The SNX is exchanged into ETH over two transactions. All funds are recovered.
Description of Potential Exploit
There are two ways to mint xSNX: by sending ETH or sending SNX. The vulnerability related to minting with ETH.
When minting with ETH, the contract transfers the ETH to Kyber, which in turns sources SNX via its own reserve or Uniswap. The mint function takes a
minRate parameter that is passed to the Kyber swap function.
samczsun outlined an exploit where an attacker could:
- 1) flash loan a large quantity of ETH
- 2) purchase a large quantity of SNX from both Uniswap V1 and Uniswap V2 driving up the SNX/ETH rate
- 3) mint xSNX with a large amount of ETH and a negligible
minRate, essentially accepting any return amount of SNX
At this point, it’s relevant to note that both xSNX mint functions calculate contribution to NAV using the Synthetix SNX oracle price feed as an input. This was done in order to calculate token price equitably between the two mint functions, but it also exposed the following vulnerability: the actual SNX acquired in the mint function in step #3 would be far less than the oracle price would suggest.
- 4) sell the large quantities of SNX acquired in Step #2 back to Uniswap V1 and V2.
The combination of steps #2 and #4 results in a slight ETH loss, but in the meantime, the attacker has acquired a disproportionate quantity of xSNX — paid for by that slight ETH loss.
- 5) repeatedly trade xSNX for SNX or ETH on Balancer until the full minted quantity has been sold off
We want to thank Sam and Georgios for their help identifying and protecting against this vulnerability. We’ve sent them a bug bounty for their vigilance and integrity.
And we want to thank the Synthetix community for being so supportive over a difficult couple days. We’re looking forward to launching a safer xSNX very soon.