On 27th October 2022, Team Finance lost $14.5 million due to a smart contract exploit in its migration function. The “v2 to v3 migration function” – the one that caused the exploit – was added a few months after the audit completion by Hacken.
After they added the “migrate” functionality, Team Finance chose Zokyo as their auditor. Zokyo flagged two vulnerabilities in the said function as critical, but the contract was nevertheless exploited. What went wrong? Let’s review the case to see how the attack unfolded.
When Hacken audited smart contracts for Team Finance, the scope did not contain the “v2 to v3 migration function,” which was exploited in October 2022.
In February 2022, Hacken auditors reviewed and analyzed the smart contract for Team Finance contracts of Trust Swap.
The audit was conducted between January 19th, 2022 – February 2nd, 2022, months before Team Finance added the exploited functionality.
At the time of the audit, the scope included three smart contracts:
Location of GitHub Repository: https://github.com/trustswap/team-finance-contracts
In our audits, we found 2 medium and 2 low-level issues in the following functions: createMultipleLocks and lockTokens, both in the LockToken.sol contract. These functions have never been exploited. On top of that, the notorious “v2 to v3 migration function” was not featured in the contracts that Hacken audited back in February 2022.
On 8th August 2022, Zokyo delivered a smart contract audit report for TrustSwap.
Zokyo Smart Contract Audit: TrustSwap (token lock) audit report.pdf
The first audit revision:
The second audit revision:
The contracts audited by Zokyo:
In their audit report on Page 8, Zokyo showed a detailed breakdown of “migrate” function.
They described “v2 to v3 migration” functionality, “Migrates liquidity to v3 by burning v2 liquidity and minting a new position for v3. Initializes the pool if it has not been initialized yet. Refunds Ether or tokens. Updates token details.”
Zokyo auditors found two critical vulnerabilities in Team Finance contracts, including issues in migrate() function: use of arbitrary token addresses and reentrancy in main functions.
Zokyo did audit the “v2 to v3 migration” function and flagged it as critical. In both cases, Zokyo recommended using the nonReentrant() modifier. Team Finance responded to these critical issues post audit, “TrustSwap team verified that this is an intended logic and users should be able to use arbitrary token addresses.” On paper, Zokyo found the critical issue. TeamFinance verified it. The exploit nevertheless happened. So what went wrong?
Hacken’s Head of the Smart Contracts Audits Department offered the following explanation for the hack and found the issue:
The exploit happened due to the vulnerability in the ‘migrate’ function.
The code lacked input parameters validation, parameters that go directly into the v3migrator.
First, ensure ‘pair’ and ‘tokenAmount’ input parameters match the ones from the ‘lockedERC20’ structure stored on the contract.
Second, ensure the validity of some other parameters.
At first glance, it appears Zokyo spotted the issue. They did flag it as critical. But if we dive deeper, we see that Zokyo was very close to finding the issue, but couldn’t get to the bottom of it. It should have been formulated differently.
The issue in the Zokyo report is about the missing whitelist for tokens. However, even if the whitelist was added, the real vulnerability would still be in the code. Whitelist does not solve the problem! You can still deposit whitelisted tokens and exploit the system.
Luckily, funds were returned to TeamFinance. But the whole crypto ecosystem has something to learn about in this case.
Adding/updating functionality to the code changes it. The audit is no longer relevant after the code changes. To stay relevant and detect new vulnerabilities, projects must audit the contract after introducing any changes. Team Finance did audit the code after introducing new changes. Unfortunately, Zokyo couldn’t fully detect a real critical weakness.
Audit is relevant only when audited code fully matches deployed code
Is the audit still relevant?
✅ Option 1 – no changes made. Answer: Yes, the audit is still relevant because the deployed version fully matches the code.
❌ Option 2 – changes were released. Answer: No, the audit is irrelevant, as we cannot guarantee its safety or what weaknesses it has now.
This certainly is a hard lesson for those involved, but Web3 players must understand that hackers aren’t going anywhere. Bad actors will always look for weaknesses they can exploit to steal funds. In response, Web3 projects must pay more attention to security. Audit relevancy is vital for smart contract security. It’s necessary to perform external code reviews after all significant changes to the code. For everyone interested in audit relevancy and checking whether the audited code matches the deployed code, we recommend monitoring CER.live – the biggest independent database of crypto audits.
For auditors, the lesson is to be a bit more persistent, especially when it comes to critical issues. Finding and conveying all possible vulnerabilities is really difficult, but that’s what makes you an exceptionally good auditor. At the end of the day, the auditor vouches for the final score with their reputation.
Subscribe to our newsletter
Enter your email address to subscribe to Hacken Reseach and receive notifications of new posts by email.