As you probably already know, Kord.Fi tzBTC contract was attacked on the night of 11th December. This page provides insights into how this happened and explains why new contracts no longer have the same vulnerabilities ad the old ones.
Kord.Fi tzBTC contract serves two purposes:
- tzBTC lending, which allows users to lend their tzBTC tokens to the Kord tzBTC contract in order to earn a dynamic secure yield on them
- SIRS leveraged farming with tzBTC loans, where users invest tez, borrow tzBTC from the lending pool (created through the funds provided by the Lenders) and invest the proceeds to theSIRS contract (thus providing liquidity to the tez/tzBTC Liquidity baking/Sirius dex)
The attacker used two weaknesses that neither Kord.Fi team nor auditors were aware of, that mostly arose from the features of tzBTC contract itself.
Firstly, we did not account for the tzBTC FA1.2 contract method peculiarity. In the special case when the transfer is called from an account that is the same as the sender, the allowance is ignored. So that self-approval is redundant and will be ignored.
Secondly, the previous iteration of Kord.Fi tzBTC contract didn’t explicitly forbid it to interact with itself.
The attacker managed to use these two weaknesses to make Kord.Fi tzBTC deposit tzBTC to itself.
Namely, this was the transaction we are talking about (https://tzkt.io/ooui7Tk5BYv4ZADPtAGEkM2G4FfRLnGHudBBn13LohzGpZvHxmB/42697841) that made the Kord tzBTC contract deposit 18598160063179.18481227 tzBTC to itself.
This had a negative impact on the operation of the contract.
- Firstly, this led to almost zero utilization and zero lending and borrowing rates (as at least formally the sum borrowed now was of a microscopic size compared to nominal deposit size).
- Secondly, Kord tzBTC contracts' Farming side became non-operational. Namely, since the contracts’ entrypoints that operate farms (investLB, redeemLB) explicitly check that the amounts of tzBTC and dtzBTC (Kord tzBTC deposits) match each other the discrepancy between the two numbers automatically caused an error as the huge amounts of dtzBTC were minted without actual tzBTC commited to that operation.
To the best of our knowledge, it was not possible for the attacker to anyhow withdraw users’ funds from the contract. At the same time, the protocol users were also unable to open or redeem farms deposits from the contract, as the contract had inconsistent tzBTC deposits
Shortly after the attack, the *EZner user withdrew a part of his deposit, which made it impossible to revert the attacker’s transaction with getBalance + callback_redeem combination. Such an attempt was made by someone but failed to revert the contract to an operational state.
The solution we used to fix the issue and release the funds was made possible by the use of getAllowance function. We applied instead of getBalance to deposit or redeem arbitrary amounts of tzBTC from the contract to itself. This helped us fix the tzBTC deposits and make the contract operational again.
The scenario described above together with many other potential attack vectors has been addressed by our joint security audit with the Inference team. This gives us the confidence in the new, extra secure Kord.Fi protocol!