TempleGold

TempleDAO
Foundry
25,000 USDC
View results
Submission Details
Severity: medium
Invalid

Potential for reentrancy attack in `TempleGold.sol::distribute()`

Summary

in distribute() the tokens are minted then totalDistributed is updated. This may lead to reentrancy where the attacker can mint new tokens since the totalGoldMinted is used in determining what number of new tokens will be distribute.

Vulnerability Details

Attacker calls mintwhich will checks how many coins to be minted according to the totalDistrubeted. but once the notifyDistrubtion is called an attacker can reenter calling mint again and since totaldistrubed tokens was not updated same params will be used minting new tokens.

Impact

lose of funds

Tools Used

manual

Recommendations

change the state of totalDistributedTokens then mint new tokens.

function _distribute(
DistributionParams storage params,
uint256 mintAmount
) private {
+ _totalDistributed += mintAmount;
uint256 stakingAmount = TempleMath.mulDivRound(
params.staking,
mintAmount,
DISTRIBUTION_DIVISOR,
false
);
if (stakingAmount > 0) {
_mint(address(staking), stakingAmount);
staking.notifyDistribution(stakingAmount);
}
uint256 escrowAmount = TempleMath.mulDivRound(
params.escrow,
mintAmount,
DISTRIBUTION_DIVISOR,
false
);
if (escrowAmount > 0) {
_mint(address(escrow), escrowAmount);
escrow.notifyDistribution(escrowAmount);
}
uint256 gnosisAmount = mintAmount - stakingAmount - escrowAmount;
if (gnosisAmount > 0) {
_mint(teamGnosis, gnosisAmount);
/// @notice no requirement to notify gnosis because no action has to be taken
}
//@audit state changed later....
- _totalDistributed += mintAmount;
emit Distributed(
stakingAmount,
escrowAmount,
gnosisAmount,
block.timestamp
);
}
function _getMintAmount(
VestingFactor memory vestingFactorCache
) private view returns (uint256 mintAmount) {
uint32 _lastMintTimestamp = lastMintTimestamp;
uint256 totalSupplyCache = _totalDistributed;
/// @dev if vesting factor is not set, return 0. `_lastMintTimestamp` is set when vesting factor is set
if (_lastMintTimestamp == 0) {
return 0;
}
mintAmount = TempleMath.mulDivRound(
//0
(block.timestamp - _lastMintTimestamp) * (MAX_SUPPLY),
vestingFactorCache.numerator,
vestingFactorCache.denominator,
false
);
if (totalSupplyCache + mintAmount > MAX_SUPPLY) {
unchecked {
mintAmount = MAX_SUPPLY - totalSupplyCache;
}
}
}
Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Lack of quality

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.