31597 - [SC - High] Loss of precision while calculating claimable f...
Submitted on May 21st 2024 at 16:09:53 UTC by @savi0ur for Boost | Alchemix
Report ID: #31597
Report type: Smart Contract
Report severity: High
Target: https://github.com/alchemix-finance/alchemix-v2-dao/blob/main/src/FluxToken.sol
Impacts:
Contract fails to deliver promised returns, but doesn't lose value
Description
Bug Description
https://github.com/alchemix-finance/alchemix-v2-dao/blob/f1007439ad3a32e412468c4c42f62f676822dc1f/src/VotingEscrow.sol#L38
/// @notice Multiplier for the slope of the decay
uint256 public constant MULTIPLIER = 2;https://github.com/alchemix-finance/alchemix-v2-dao/blob/f1007439ad3a32e412468c4c42f62f676822dc1f/src/VotingEscrow.sol#L44
int256 internal constant iMULTIPLIER = 2;https://github.com/alchemix-finance/alchemix-v2-dao/blob/f1007439ad3a32e412468c4c42f62f676822dc1f/src/VotingEscrow.sol#L1157-L1160
function _calculatePoint(LockedBalance memory _locked, uint256 _time) internal pure returns (Point memory point) {
if (_locked.end > _time && _locked.amount > 0) {
point.slope = _locked.maxLockEnabled ? int256(0) : (int256(_locked.amount) * iMULTIPLIER) / iMAXTIME;
point.bias = _locked.maxLockEnabled
? ((int256(_locked.amount) * iMULTIPLIER) / iMAXTIME) * (int256(_locked.end - _time))
: (point.slope * (int256(_locked.end - _time)));
}
}As we can see, iMULTIPLIER and MULTIPLIER is set to 2, which is not sufficient to preserve the precision.
point.slope and point.bias are calculated as follow:
When (int256(_locked.amount) * iMULTIPLIER) < iMAXTIME and ((int256(_locked.amount) * iMULTIPLIER) < iMAXTIME, it results in zero. So for the locked amounts which is small enough when multiplied by iMULTIPLIER=2 end up being lower than iMAXTIME, will not be counted in bias and slope calculation. At that point in time, there slope and bias will be zero.
For example,
As we can, both slope and bias become zero.
https://github.com/alchemix-finance/alchemix-v2-dao/blob/f1007439ad3a32e412468c4c42f62f676822dc1f/src/FluxToken.sol#L224
Similarly, in getClaimableFlux function, claimableFlux is calculated as
Here also, veMul = 2 as its fetched from VotingEscrow's multiplier.
Impact
Precision loss while calculating claimable flux and point's bias and slope.
Recommendation
Increase MULTIPLIER and iMULTIPLIER precision from 2 to 1e18, for higher precision.
References
https://github.com/alchemix-finance/alchemix-v2-dao/blob/main/src/VotingEscrow.sol
https://github.com/alchemix-finance/alchemix-v2-dao/blob/main/src/FluxToken.sol
Proof Of Concept
Steps to Run using Foundry:
Paste following foundry code in
src/test/FluxToken.t.solRun using
FOUNDRY_PROFILE=default forge test --fork-url $FORK_URL --fork-block-number 17133822 --match-contract FluxTokenTest --match-test testPrecisionLoss -vv
Console Output:
As we can see, by increasing MULTIPLIER, precision has increased. We have used 200000 as MULTIPLIER here to show precision issue as it was set 2 initially.
Last updated
Was this helpful?