Root + Impact
Shares minted to wrong address, breaking deposit-on-behalf functionality.
Description
function deposit(uint256 assets, address receiver) public override returns (uint256) {
require(receiver != address(0));
stakedAsset[receiver] = stakeAsset;
_mint(msg.sender, participantShares);
}
Risk
Likelihood:
Impact:
Proof of Concept
Here is a PoC of calling deposit method from alice and sending bob as a receiver
alice.deposit(1000, bob);
bob.joinEvent(0);
alice.joinEvent(0);
Recommended Mitigation
There can be multiple mitigations, like removing of receiver address and all the states update for the msg.sender, another mitigation will be using receiver address and all states updates for the receiver
Mitigation-1: Using of msg.sender
function deposit(uint256 assets) public override returns (uint256) {
- require(receiver != address(0));
uint256 stakeAsset = assets - fee;
- stakedAsset[receiver] = stakeAsset;
+ stakedAsset[msg.sender] = stakeAsset;
uint256 participantShares = _convertToShares(stakeAsset);
IERC20(asset()).safeTransferFrom(msg.sender, participationFeeAddress, fee);
IERC20(asset()).safeTransferFrom(msg.sender, address(this), stakeAsset);
_mint(msg.sender, participantShares);
- emit deposited (receiver, stakeAsset);
+ emit deposited (msg.sender, stakeAsset);
return participantShares;
}
Mitigation-2: Using of receiver
function deposit(uint256 assets, address receiver) public override returns (uint256) {
require(receiver != address(0));
uint256 stakeAsset = assets - fee;
stakedAsset[receiver] = stakeAsset;
uint256 participantShares = _convertToShares(stakeAsset);
- IERC20(asset()).safeTransferFrom(msg.sender, participationFeeAddress, fee);
+ IERC20(asset()).safeTransferFrom(receiver, participationFeeAddress, fee);
- IERC20(asset()).safeTransferFrom(msg.sender, address(this), stakeAsset);
+ IERC20(asset()).safeTransferFrom(receiver, address(this), stakeAsset);
- _mint(msg.sender, participantShares);
+ _mint(receiver, participantShares);
emit deposited (receiver, stakeAsset);
return participantShares;
}