Summary
User can get infinite funds on L2
Vulnerability Details
In order for ownable contracts that have deposits in Beanstalk to be able to migrate, a merkle tree is set and signatures from the owner is required. Then, using the merkle tree and the signature, the owner would be able to claim the funds on the L2.
function redeemDepositsAndInternalBalances(
address owner,
address reciever,
AccountDepositData[] calldata deposits,
AccountInternalBalance[] calldata internalBalances,
uint256 ownerRoots,
bytes32[] calldata proof,
uint256 deadline,
bytes calldata signature
) external payable fundsSafu noSupplyChange nonReentrant {
verifyDepositsAndInternalBalances(owner, deposits, internalBalances, ownerRoots, proof);
verifySignature(owner, reciever, deadline, signature);
uint256 accountStalk;
for (uint256 i; i < deposits.length; i++) {
accountStalk += addMigratedDepositsToAccount(reciever, deposits[i]);
}
setStalk(reciever, accountStalk, ownerRoots);
}
function verifyDepositsAndInternalBalances(
address account,
AccountDepositData[] calldata deposits,
AccountInternalBalance[] calldata internalBalances,
uint256 ownerRoots,
bytes32[] calldata proof
) internal pure {
bytes32 leaf = keccak256(abi.encode(account, deposits, internalBalances, ownerRoots));
require(MerkleProof.verify(proof, MERKLE_ROOT, leaf), "Migration: invalid proof");
}
function verifySignature(
address owner,
address reciever,
uint256 deadline,
bytes calldata signature
) internal view {
require(block.timestamp <= deadline, "Migration: permit expired deadline");
bytes32 structHash = keccak256(
abi.encode(REDEEM_DEPOSIT_TYPE_HASH, owner, reciever, deadline)
);
bytes32 hash = _hashTypedDataV4(structHash);
address signer = ECDSA.recover(hash, signature);
require(signer == owner, "Migration: permit invalid signature");
}
The problem is that even upon a successful call, the merkle leaf is never set to used. This allows the owner to repeatedly call the function and receive funds each time.
Impact
Infinite minting of assets
Tools Used
Manual review
Recommendations
Upon a successful call, mark the leaf
as used.