Docile Cerulean Zebra
Medium
If ERC20VariableIncentive
and ERC20Incentive
get disbursed multiple times, additional funds may get locked forever
The ERC20VariableIncentive
can be disbursed multiple times, but when this happens, the extra disbursed amount will be locked in contract forever.
ManagedBudget::disburse
allows budget owners to provide assets/liquidity for incentives, this function is called when incentives are being deployed, but owners can also call it later if they want to put more into incentives, the function does a simple job, to transfer correspond types of assets to the target address, in this case, the incentive contracts.
function disburse(bytes calldata data_)
public
virtual
override
onlyOwnerOrRoles(ADMIN_ROLE | MANAGER_ROLE)
returns (bool)
{
Transfer memory request = abi.decode(data_, (Transfer));
if (request.assetType == AssetType.ERC20 || request.assetType == AssetType.ETH) {
FungiblePayload memory payload = abi.decode(request.data, (FungiblePayload));
uint256 avail = available(request.asset);
if (payload.amount > avail) {
revert InsufficientFunds(request.asset, avail, payload.amount);
}
_transferFungible(request.asset, request.target, payload.amount);
} else if (request.assetType == AssetType.ERC1155) {
ERC1155Payload memory payload = abi.decode(request.data, (ERC1155Payload));
uint256 avail = IERC1155(request.asset).balanceOf(address(this), payload.tokenId);
if (payload.amount > avail) {
revert InsufficientFunds(request.asset, avail, payload.amount);
}
_transferERC1155(request.asset, request.target, payload.tokenId, payload.amount, payload.data);
} else {
return false;
}
return true;
}
In ERC20VariableIncentive
contract, when it gets clawed back, limit
will be deducted by the withdrawn amount:
function clawback(bytes calldata data_) external override onlyOwner returns (bool) {
ClawbackPayload memory claim_ = abi.decode(data_, (ClawbackPayload));
(uint256 amount) = abi.decode(claim_.data, (uint256));
limit -= amount;
// Transfer the tokens back to the intended recipient
asset.safeTransfer(claim_.target, amount);
emit Claimed(claim_.target, abi.encodePacked(asset, claim_.target, amount));
return true;
}
As limit
is a fixed constant, so when more assets are disbursed to this incentive, they will not be distributed, and when it exceeds certain amount, those extra ones cannot be clawed back either, as limit
will go as low as zero, and anything beyond that will make clawback
revert.
No response
No response
No response
Additional assets disbursed will be locked forever.
- Boost owner sets up a boost, and disbursed 1000 USDC to the
ERC20VariableIncentive
incentive, and sets limit to 1000 as well. - After 500 USDC has been claimed, the budget admin/owner wants to add additional 2000 USDC to the incentive.
- At most 500 more USDC can be claimed, as more would exceeds limit set earlier.
- Budget owner tries to call
clawback
to get the extra USDC back, but they can only get 1000 back, as the limit is 1000, the rest 1000 will be locked forever.
For incentives, add an entry for more disburse, and sets the value or revert the call accordingly.