Skip to content

Latest commit

 

History

History
18 lines (11 loc) · 2.32 KB

README.md

File metadata and controls

18 lines (11 loc) · 2.32 KB

Solution

This challenge leverages a staking contract for a token, which inherits functionalities from two critical contracts: Multicall and ERC2771Context. Multicall facilitates the execution of multiple contract calls within a single transaction, enhancing transaction efficiency. Concurrently, ERC2771Context introduces the concept of meta-transactions, thereby enabling relayers to submit transactions on behalf of users, with the added benefit of relayers covering the associated gas fees.

A pivotal vulnerability, as detailed in this blog post, arises from the exploitable delegatecall feature found within Multicall. This feature can be manipulated to alter the resolution of _msgSender() in subsequent calls that originate from the ERC2771Context forwarder. Such manipulation renders the contract susceptible to attacks that utilize spoofed calls, thus compromising its integrity.

To solve the challenge, the objective is to amass a significant number of tokens through staking and subsequently transfer a predetermined amount to the address 0x123. The first step involves manipulating the contract's reward rate by assuming the identity of the contract owner. This is achieved by invoking the notifyRewardAmount function—a mechanism that traditionally restricts execution to the owner by verifying that _msgSender() matches the owner address. The argument supplied to this function should be carefully calculated to yield the exact amount of rewards destined for transfer to the address 0x123, as stipulated by the Challenge contract.

To be specific, the order of calls should be:

  • Solver -> Forwarder -> Multicall (Staking) -> Itself (Staking) -> notifyRewardAmount function
  • Solver -> Staking -> stake function
  • Solver -> Staking -> getReward function
  • Solver -> Token -> transfer function

After successfully inflating the reward rate, the next phase involves depositing tokens into the staking contract. After allowing some time for reward accumulation—typically spanning a few blocks—the accrued tokens are withdrawn, the rewards are claimed, and the requisite amount is transferred to the address 0x123.

The challenge is now solved and we can get the flag!