Lines of code
<https://github.com/code-423n4/2023-12-autonolas/blob/main/tokenomics/contracts/Treasury.sol#L402-L410>
The potential issue identified in the Treasury.rebalanceTreasury()involves the risk of failing to transfer treasury rewards from ETHFromServices to ETHOwned due to insufficient funds in ETHFromServices. This situation can arise when the withdrawToAccount function, called by the dispenser contract, excessively depletes the ETHFromServices balance, leaving an insufficient amount for the annual reward rebalancing.
This can disrupt the intended economic mechanisms of the contract, potentially affecting the treasury’s ability to accumulate and manage its rewards effectively. If left unaddressed, this could lead to financial discrepancies, undermining the contract’s economic model.
Here’s a typical scenario:
if (incentives[1] == 0 || ITreasury(treasury).rebalanceTreasury(incentives[1])) {
if (treasuryRewards > 0) {
uint256 amountETHFromServices = ETHFromServices;
if (amountETHFromServices >= treasuryRewards) {
// Update ETH from services value
amountETHFromServices -= treasuryRewards;
// Update treasury ETH owned values
uint256 amountETHOwned = ETHOwned;
amountETHOwned += treasuryRewards;
// Assign back to state variables
ETHOwned = uint96(amountETHOwned);
ETHFromServices = uint96(amountETHFromServices);
emit UpdateTreasuryBalances(amountETHOwned, amountETHFromServices);
} else {
// There is not enough amount from services to allocate to the treasury
success = false;
}
}
if (accountRewards > 0 && amountETHFromServices >= accountRewards) {
amountETHFromServices -= accountRewards;
ETHFromServices = uint96(amountETHFromServices);
emit Withdraw(ETH_TOKEN_ADDRESS, account, accountRewards);
(success, ) = account.call{value: accountRewards}("");
if (!success) {
revert TransferFailed(address(0), address(this), account, accountRewards);
}
uint256 eCounter = epochCounter;
TokenomicsPoint storage tp = mapEpochTokenomics[eCounter];
// 0: total incentives funded with donations in ETH, that are split between:
// 1: treasuryRewards, 2: componentRewards, 3: agentRewards
// OLAS inflation is split between:
// 4: maxBond, 5: component ownerTopUps, 6: agent ownerTopUps
uint256[] memory incentives = new uint256[](7);
incentives[0] = tp.epochPoint.totalDonationsETH;
incentives[1] = (incentives[0] * tp.epochPoint.rewardTreasuryFraction) / 100;
if (incentives[1] == 0 || ITreasury(treasury).rebalanceTreasury(incentives[1])) {
Manual
Consider setting a threshold mechanism that could be implemented in the withdrawToAccount function. This threshold would ensure that a certain amount of ETH is always reserved in ETHFromServices for the treasury’s rewards.
Timing
The text was updated successfully, but these errors were encountered:
All reactions