Summary
TempleGold::circulatingSupply()
function is supposed, according to the natSpec, to return the circulating supply of each chain, except when called on Arbitrum
, which then returns the circulating supply across all chains. But this is not the case.
* @notice Get circulating supply on this chain
* @dev When this function is called on source chain (arbitrum), you get the real circulating supply across chains
* @return Circulating supply
*/
function circulatingSupply() public view override returns (uint256) {
return _totalDistributed;
}
Vulnerability Details
Calling TempleGold::circulatingSupply()
in any chain apart from Arbitrum
will always return 0
. The function returns _totalDistributed
which is only updated during minting/distributing of tokens, which is only possible to happen in the Arbitrum
chain.
uint256 private _totalDistributed;
function mint() external override @> onlyArbitrum <@ {
VestingFactor memory vestingFactorCache = vestingFactor;
DistributionParams storage distributionParamsCache = distributionParams;
if (vestingFactorCache.numerator == 0) revert ITempleGold.MissingParameter();
uint256 mintAmount = _getMintAmount(vestingFactorCache);
if (!_canDistribute(mintAmount)) return;
lastMintTimestamp = uint32(block.timestamp);
@> _distribute(distributionParamsCache, mintAmount);
}
function _distribute(DistributionParams storage params, uint256 mintAmount) private {
uint256 stakingAmount = TempleMath.mulDivRound(params.staking, mintAmount, DISTRIBUTION_DIVISOR, false);
if (stakingAmount > 0) {
.
.
.
@> _totalDistributed += mintAmount;
emit Distributed(stakingAmount, escrowAmount, gnosisAmount, block.timestamp);
}
Impact
The function doesn't work as expected and will always return wrong results.
Tools Used
Manuel Review
Recommendations
If not on Arbitrum
chain, make the TempleGold::circulatingSupply()
function to return the totalSupply()
of the token.