Alchemix Access Control Issue Bugfix Review

Immunefi Editor
Immunefi
Published in
7 min readJun 14, 2024

--

Summary

On September 23, 2023, the security researcher Koiush submitted a high vulnerability to Alchemix via Immunefi, which consisted of improper configuration of access control for harvesting of yield.

At the time of the submission, the vulnerability would have allowed an attacker to steal yield generated during harvesting in rETH, stETH, and FraxETH pools.

After receiving Koiush’s report, the bug was quickly neutralized by Alchemix’s team with no impact to user funds. Alchemix promptly awarded a bounty of 1,000 ALCX ($28,730) to Koiush for this finding.

Immunefi is pleased to have facilitated this responsible disclosure with our platform. Our goal is to make web3 safer by incentivizing hackers to responsibly disclose bugs and receive clean money and reputation in exchange.

Introduction to Alchemix

Let’s break it down. Alchemix Finance is primarily a synthetic asset protocol that centers around the idea of tokenizing “future yield”.

To achieve this, it has a family of synthetic assets with the prefix “al-” (alETH, alUSD) which allow users to borrow against their yield-accruing deposits in lending/borrow protocols, accessing some portion of this “future” yield upfront.

How it works is, users deposit yield-bearing variants of ETH and DAI, USDC, etc. and then borrow alETH or alUSD against their value. The al-assets can be redeemed for the underlying collateral at any time with some time delay (transmuting), or exchanged instantly at the market rate for any token of value (swap). This system of exchange forms the basis of value, and the main utility of the protocol.

The Alchemix protocol features “Alchemists”, which are the central smart contracts powered by AlchemistV2.sol. This allows users to deposit yield-bearing or underlying assets as collateral in the protocol. Multiple yield strategies are supported in this format, but each “Alchemist” is dedicated to issuing a specific alAsset, such as alUSD.

Alchemix smart contracts allows users to borrow only up to 50% of their collateral’s value, ensuring that all borrowing across the protocol is collateralized by at least 200% in valuable yield-bearing assets. The accrued yield is periodically harvested from these assets, which is then put to work reducing the user’s debt or increasing the user’s borrowing limit if no debt is taken.

To accrue yield, the harvest() function must be periodically called on the Harvester contract. Alchemix utilized Gelato, a smart contract automation service, to manage calls to the harvest() function automatically, ensuring that users can passively earn yield without needing to manually interact with the protocol.

Gelato

Gelato is a Web3 serverless cloud platform that provides roll ups as a service and offers a suite of Web3 Services, such as Functions, Account Abstraction Infrastructure, VRF, and more. Alchemix utilized Gelato’s Web3 Functions system designed to manage and automate smart contract tasks.

The Web3 Functions Automate contract allows projects to create tasks which are analyzed and executed automatically by Gelato’s off-chain cloud services. When a task is created, the following parameters must be specified:

  • _execAddress, which is the target of the call
  • _execDataOrSelector, which is the function to be called by the automated keeper
  • _moduleData which are any conditions / specifications about the task
  • feeToken, which is the optional fee token.

Calling the createTask function in the Automate contract emits the TaskCreated event, which is registered by Gelato’s off-chain services to later be executed by the Automate contract through exec.

Optionally, task’s creators have the ability to specify the created task to be executed through a dynamically generated proxy contract by setting the proxy module to PROXY type. This allows target contracts to whitelist the generated proxy contract and limit access to the automated function through onlyDedicatedMsgSender, instead of the call originating from the generic Automate contract which allows any user to create and execute tasks to trigger functionality of a target contract.

Alchemix Harvester

The AlchemixHarvester contract enables the Alchemix contracts to collect outstanding yield from underlying assets and distribute it to token holders.​​ The harvest function in AlchemixHarvester is a proxy for the call to AlchemixV2 contract’s harvest function, where the majority of the logic exists. Within the harvest function, yield tokens are unwrapped for their underlying asset and sent to the Transmuter. The _unwrap function is a critical component that makes a call to the specified yield token’s TokenAdapter contract, which handles the actual unwrapping of the yield-bearing collateral token to the underlying token of a Vault.

Due to some token adapters utilizing Balancer swaps (Balancer is an exchange protocol) to unwrap yield-bearing tokens to collect on accrued yield, the harvest function can be susceptible to MEV attacks (Miner or Maximal Extractable Value, also known as sandwich attacks) which manipulate the price of the asset before and after the unwrapping occurs. Normally, this isn’t an issue, since the harvest function provides a parameter to specify the `minimumAmountOut` for unwrapping.

However, since the AlchemixHarvester contract restricts access to the harvest function by only specifying the caller to be the generic Automate contract address, anyone could create a Gelato task which calls the harvest function with arbitrary parameters.

Vulnerability Analysis

Access control, or the lack of it, is at the heart of this vulnerability. Having proper checks is crucial for limiting access to important assets and functions, ensuring the security and continued safe operation of your smart contracts. Due to its ubiquity, it was found as #4 of the top 10 most common smart contract vulnerabilities identified by Immunefi in 2023.

Alchemix’s Gelato task was not created as a PROXY, meaning the Automate contract would directly call the target contract. This means the harvester contract had to whitelist the Automate contract for the harvest function execution to succeed. However, since Gelato task creation through the Automate contract is permissionless and the same contract will be used for execution unless the task is specified to use a dedicated msg.sender, anyone could create a task which would call the AlchemixHarvester contract and trigger a harvest with arbitrarily specified parameters. An attacker could create a Gelato task that targets the AlchemixHarvester and specify 1 for the minimumAmountOut, which would make the harvest call vulnerable to sandwich attacks.

The attack could be further escalated by specifying a custom contract as the alchemist parameter, causing the resolver to record a harvest, but not actually harvest any yield. This would prevent the Gelato keeper from calling the harvest function, since it utilizes the checker function of the resolver to determine if the conditions for calling harvest have arrived. Blocking the harvest of yield would allow an attacker to accumulate higher unharvested amounts in the vault so the final attack can be more profitably sandwiched.

Editor’s note: the ability to look for ways to maximize profit such as blocking the harvest is an essential skill to learn for whitehats wanting to demonstrate the maximum impact for their vulnerability. Take note of this if you would like to improve your bug-hunting experience!

Of the six ETH-type assets that could be targeted by this attack, there were only three token adapters that had unwrap functions which were vulnerable to sandwiching. And of the three, only the rETH adapter was vulnerable to profitable sandwiching at the time of submission due its configuration best matching the requirements for the attack.

Proof of Concept (PoC):

The Immunefi team prepared the following PoC to demonstrate the vulnerability. You are encouraged to follow along by using Foundry to produce the results and examine them on your own.

The attack first creates a Gelato task to call the AlchemixHarvester contract with a minAmountOut of 1. The attacker would then trigger their automation for the Gelato keeper to call the harvest function, and sandwich the vulnerable swap. The attacker front runs the harvest transaction and manipulates the Balancer pool which is utilized for the unwrapping of rETH in the Alchemix adapter. The attacker can now manipulate the balancer rate back down to recover the collateral deposited for each account in the same block, and is now left with a portion of the accrued WETH.

In the following PoC, an arbitrary harvest transaction call was utilized as a baseline for the amount of yield that would have been accrued in the transmuter and treasury during normal operation operation. The PoC then demonstrates the impact of the attack if the vulnerable harvest call was triggered and subsequently sandwiched by the attacker.

As we can see, after running the PoC, our test scenario resulted in a profit of 4.975 rETH for the exploiter.

Vulnerability Fix

Since AlchemixHarvesters are immutable, and the gelato poker address is set during contract creation, Alchemix would need to migrate Harvesters and update the contracts to utilize a dedicated msg.sender instead of the generic Automate contract address. The contracts were redeployed with an EOA set as the _gelatoPoker.

This remediated the access control issue by replacing the gelato poker address with an Alchemix-controlled EOA.

Acknowledgements

We would like to thank Koiush for doing an amazing job and responsibly disclosing such an important bug. Big props also to the Alchemix team who responded quickly to the report and patched the bug.

This bugfix review was written by Immunefi triager, Alejandro Muñoz-McDonald.

If you’d like to start bug hunting, we got you. Check out the Web3 Security Library, and start earning rewards on Immunefi — the leading bug bounty platform for web3 with the world’s biggest payouts.

If you’re feeling good about your skillset and want to see if you will find bugs in the code, check out the bug bounty program from Alchemix.

--

--

Immunefi Editor
Immunefi

Writing for the premier bug bounty platform of Web3.