Distribution's claim function does not update storage variables
Description
In Distributor, the claim function does not work correctly. The poolInfo is not updated after the claim, so the amountToDistribute is not updated. Since the balance decreases while the amountToDistribute remains the same, once the first claim occurs, other users will not be able to make a claim.
function claim(address _pool) external whenNotPaused() nonReentrant() {
require(_pool != address(0), UnsupportedPool());
// ...
PoolInfo memory poolInfo = poolInfos[_pool];
// check if pool has enough *allocated* shares to distribute
if (poolInfo.amountToDistribute < shares) {
revert NotEnoughSharesToDistribute();
}
// check if the distributor has enough shares tokens as the amount to distribute
if (IERC20(couponToken).balanceOf(address(this)) < poolInfo.amountToDistribute) {
revert NotEnoughSharesToDistribute();
}
poolInfo.amountToDistribute -= shares;
couponAmountsToDistribute[couponToken] -= shares;
// ...
}Impact
If there are no other pools sharing the coupon token, a revert will occur from the second claimant onward due to the unupdated amountToDistribute. If such pools exist, it will ultimately cause a balance mismatch, putting the protocol at risk.
The following proof-of-concept script demonstrates that the second claimant receives a revert by the unupdated amountToDistribute:
function testAuditClaimFailedByPoolInfoNotUpdated() public {
Token sharesToken = Token(_pool.couponToken());
vm.startPrank(minter);
_pool.bondToken().mint(user1, 1*10**18);
_pool.bondToken().mint(user2, 1*10**18);
sharesToken.mint(address(_pool), 20004000000000000000000);
vm.stopPrank();
vm.startPrank(governance);
fakeSucceededAuction(address(_pool), 0);
vm.mockCall(
address(0),
abi.encodeWithSignature("state()"),
abi.encode(uint256(1))
);
vm.warp(block.timestamp + params.distributionPeriod);
_pool.distribute();
vm.stopPrank();
vm.startPrank(user1);
distributor.claim(address(_pool));
vm.stopPrank();
vm.startPrank(user2);
vm.expectRevert();
distributor.claim(address(_pool));
vm.stopPrank();
}Recommendations
Use storage poolInfo to update the storage variable.
Remediation
This issue has been acknowledged by Plaza Finance, and a fix was implemented in commit 70eb9503↗.