Report Date
October 20, 2022
Critical: Take funds by changing Fee Receiver Address
‣
Report ID
#12593
Target
Report type
Smart Contract
Impacts
Direct theft of any user funds, whether at-rest or in-motion, other than unclaimed yield
Has PoC?
Yes
Details
Missing access control allows to change the fee receiver address on admin contract.
Vulnerable Admin Contract
Fix
Add this line of code
assert msg.sender == self.parameter_admin
Proof of concept
Visit here
- https://etherscan.io/token/0xc9c32cd16bf7efb85ff14e0c8603cc90f6f2ee49#readContract
- It has admin https://etherscan.io/address/0x8CF8Af108B3B46DDC6AD596aebb917E053F0D72b#writeContract
- Check this function
@external
def set_fee_receiver(_target: address, _base_pool: address, _fee_receiver: address):
Factory(_target).set_fee_receiver(_base_pool, _fee_receiver)
- This function missed the owner check, allows anyone to set the fee receiver.
Exploit
- On this contract https://etherscan.io/address/0x8CF8Af108B3B46DDC6AD596aebb917E053F0D72b#writeContract
Attacker will call set_fee_receiver
 and change the fee receiver.
@external
def set_fee_receiver(_target: address, _base_pool: address, _fee_receiver: address):
Factory(_target).set_fee_receiver(_base_pool, _fee_receiver)
- Then Attacker will call withdraw_admin_fees on this contract https://etherscan.io/token/0xc9c32cd16bf7efb85ff14e0c8603cc90f6f2ee49
def withdraw_admin_fees():
factory: address = self.factory
# transfer coin 0 to Factory and call `convert_fees` to swap it for coin 1
coin: address = self.coins[0]
amount: uint256 = ERC20(coin).balanceOf(self) - self.balances[0]
if amount > 0:
ERC20(coin).transfer(factory, amount)
Factory(factory).convert_fees()
# transfer coin 1 to the receiver
coin = self.coins[1]
amount = ERC20(coin).balanceOf(self) - self.balances[1]
if amount > 0:
receiver: address = Factory(factory).fee_receiver(BASE_POOL)
ERC20(coin).transfer(receiver, amount)
- As you can see the code
Factory(factory).fee_receiver(BASE_POOL)
ERC20(coin).transfer(receiver, amount)
- It transfers funds to fee recieved address which has been already modified by attacker above.
- Finally attacker get all funds lying in the smart contract which are about $13996054 BEAN and $13673098 CURVEFI 3CRV.
BIC Response
This submission is related to an out of scope asset: the BEAN:3CRV Curve LP token. Curve pools are not part of Beanstalk and thus not included in the Immunefi bug bounty program. Curve pools are also non-upgradable.
The Beanstalk DAO acknowledges the risk of using Curve and has transparently communicated that here:
Due to these reasons, this report is not eligible for a reward.