Merlin Lab’s Incident Analysis — Improper Mint Amount Calculation on mintFor() Function

Starting from Jun 29, 2021, 07:24:29 AM UTC, attacks were done on Merlin’s Alpaca Vault due to improper mint amount calculation. In this article, we would describe the technical details of this issue step-by-step.

Related Addresses

Attack Steps

Please consider the following transaction to be the example of this incident analysis:
https://bscscan.com/tx/0x31fdf621f60684579de00f30b33fa051c19f1fd45d891c817e2a3888a9b75726

  1. Deposited 0.1 $WBNB to Merlin’s Alpaca Vault

2. Transferred 546 $WBNB and 1 $ALPACA (for bypassing the reinvest condition check when executing the harvest() function) to the vault as the reward

3. Harvested the reward to force the Merlin’s Alpaca Vault to reinvest

4. Executed WithdrawAll() which resulted in the performance fee that will be deducted from the reward and $MERL will be minted with function mintFor() as a compensation

5. In function mintFor(), the amount of $MERL that must be minted will be calculated with the performance fee multiplied by a static variable (merlinPerProfitBNB) which equals to “20 * 10^18” led to an excessive amount of minted $MERL compare to the actual $MERL price

6. Swap all minted $MERL to $WBNB to make a profit

In this transaction, the attacker deposited 0.1 $WBNB and transferred 546.81 $WBNB to Merlin’s Alpaca Vault. Then withdrew 382.70 $WBNB and swapped the 5,625.69 $MERL minted to be 246.29 $WBNB. Therefore, the attacker gained 82.78 $WBNB as shown in the following calculation:

246.29 + 382.70 - 546.81 - 0.1 = 82.78 $WBNB

Code Analysis

The attack started at the MerlinStrategyAlpacaBNB.deposit() function, which calls the internal BaseMerlinStratrgy._deposit() function. This function receives the token from the user and records the user’s shares and principal.

BaseMerlinStratrgy.sol

The attacker manually transferred $WBNB and 1 $ALPACA to the contract and called the harvest() function. The function harvests the pending reward then executes the _tryReinvest() function.

MerlinStrategyAlpacaBNB.sol

In the normal case, the _tryReinvest() function swaps the reward claimed from the harvest() function to the stakingToken and reinvest to the vault using the _depositUnderlying() function. However, as the attacker directly transferred $WBNB into the contract, the balance deposited was seen as a reward.

The 1 $ALPACA was transferred to the contract to fulfill the condition in line 209.

MerlinStrategyAlpacaBNB.sol

After that, the attacker called the withdrawAll() function to trigger the final step of the attack. The token is withdrawn using the _withdrawUnderlying() function, and the profit is calculated by comparing the amount withdrawn to the principal in line 159.

The performanceFee is then calculated from the profit, and then used in the merlinMinter.mintFor() function on line 169.

MerlinStrategyAlpacaBNB.sol

The mintFor() function calculates the contribution using the performanceFee passed into the function, which is then used to calculate the amount of $MERL to mint using the amountMerlinToMint() function.

MerlinMinter.sol

The amount is multiplied by merlinPerProfitBNB, a variable specified in the contract, to get the amount of $MERL and mint for the user.

MerlinMinter.sol

The merlinPerProfitBNB variable is defined in the contract and does not reflect to the real value of $MERL, so the minting is done excessively.

Conclusion

From this attack, using the flaw explained above, the same attack technique was performed 22 times and the attacker gained a total of 1,056.308843 $WBNB.

For the full detail of profit in each transaction, please visit:
https://docs.google.com/spreadsheets/d/19EQyMRdNktDOR4DbmSbLXeSGHmemnKqKVvgYvGS_1Wc/edit?usp=sharing

About Inspex

Inspex is formed by a team of cybersecurity experts highly experienced in various fields of cybersecurity. We provide blockchain and smart contract professional services at the highest quality to enhance the security of our clients and the overall blockchain ecosystem.

For any business inquiries, please contact us via Twitter, Telegram, contact@inspex.co

Cybersecurity professional service, specialized in blockchain and smart contract auditing https://twitter.com/InspexCo