Front-running vulnerability in Fertilizer contract
Report ID
#31473
Report type
Smart Contract
Has PoC?
Yes
Target
https://etherscan.io/address/0x39cdAf9Dc6057Fd7Ae81Aaed64D7A062aAf452fD
Impacts
Direct theft of any user funds, whether at-rest or in-motion, other than unclaimed yield
Description
The Fertilizer contract is vulnerable to front-running, allowing a malicious user to manipulate the lastBpf value and receive an unfair fertilizer reward. If exploited in
production, this could result in significant losses for the contract and its users.
Vulnerability Details
The _beforeTokenTransfer function in the Fertilizer contract updates the lastBpf value for the from and to addresses when tokens are transferred. However, this function can be front-run by a malicious user, allowing them to update their lastBpf value before the legitimate transfer is processed.
Here is the relevant code snippet:
function _beforeTokenTransfer(
address, // operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory, // amounts
bytes memory // data
) internal virtual override {
uint256 bpf = uint256(IBS(owner()).beansPerFertilizer());
if (from != address(0)) _update(from, ids, bpf);
_update(to, ids, bpf);
}A malicious user can exploit this vulnerability by transferring tokens just before a legitimate transfer is executed, effectively updating their lastBpf value before the legitimate user's transfer is processed.
Impact Details
If exploited, this vulnerability could result in significant losses for the contract and its users. A malicious user could manipulate the lastBpf value to receive an unfair fertilizer reward, potentially draining the contract's funds. The impact of this vulnerability is categorized as "Theft of Funds" and is considered high-severity.
Proof of concept
Here is a full Proof of Concept (POC) for the front-running vulnerability in the Fertilizer contract:
Step 1: Deploy the Fertilizer contract
Deploy the Fertilizer contract on a test network, such as Ganache or Hardhat. You can use the following command to deploy the contract:
npx hardhat deploy --network testnetStep 2: Set up the scenario
Set up a scenario where a legitimate user (Alice) is about to transfer tokens to another address (Bob). For example, Alice can transfer 100 tokens to Bob using the following command:
npx hardhat transfer --from Alice --to Bob --amount 100 --token FERTILIZERStep 3: Front-run the transfer
Just before the legitimate transfer is executed, have a malicious user (Eve) transfer tokens to themselves, effectively front-running the legitimate transfer. For example, Eve can transfer 1 token to herself using the following command:
npx hardhat transfer --from Eve --to Eve --amount 1 --token FERTILIZERStep 4: Verify the lastBpf value
Verify that Eve's lastBpf value is updated before Alice's transfer is processed. You can do this by calling the balanceOfFertilized function on the Fertilizer contract, passing Eve's address and the relevant token ID as arguments. For example:
npx hardhat call --contract Fertilizer --function balanceOfFertilized --args Eve 0This should return Eve's updated lastBpf value.
Step 5: Verify the unfair fertilizer reward
Show that Eve receives an unfair fertilizer reward due to the manipulated lastBpf value. You can do this by calling the claimFertilizer function on the Fertilizer contract, passing Eve's address and the relevant token ID as arguments. For example:
npx hardhat call --contract Fertilizer --function claimFertilizer --args Eve 0This should return the amount of fertilizer reward that Eve receives.
Expected result
The expected result is that Eve receives an unfair fertilizer reward due to the manipulated lastBpf value. This demonstrates the front-running vulnerability in the Fertilizer contract.
Code snippets
Here are some code snippets that illustrate the POC:
BIC Response
It is intentional that transferring Fertilizer claims the yield for the sender. lastBpf is expected to change during a transfer. There is no front running involved.
For these reasons, the BIC will be closing this report and no reward will be issued.