The values of lastRatio in the contract Buoy3Pool are not initialized (thus they have a value of 0).
If safetyCheck() would be called before the first time _updateRatios is called, then safetyCheck() would give unexpected results.
function safetyCheck() external view override returns (bool) {
for (uint256 i = 1; i < N_COINS; i++) {
uint256 _ratio = curvePool.get_dy(int128(0), int128(i), getDecimal(0));
_ratio = abs(int256(_ratio - lastRatio[i]));
if (_ratio.mul(PERCENTAGE_DECIMAL_FACTOR).div(CURVE_RATIO_DECIMALS_FACTOR) > BASIS_POINTS) {
return false;
}
}
return true;
}
function _updateRatios(uint256 tolerance) private returns (bool) {
...
for (uint256 i = 1; i < N_COINS; i++) {
lastRatio[i] = newRatios[i];
Tools Used
Recommended Mitigation Steps
Double check if this situation can occur.
Perhaps call _updateRatios as soon as possible.
Or check in safetyCheck that the lastRatio values are initialized
Handle
gpersoon
Vulnerability details
Impact
The values of lastRatio in the contract Buoy3Pool are not initialized (thus they have a value of 0). If safetyCheck() would be called before the first time _updateRatios is called, then safetyCheck() would give unexpected results.
Proof of Concept
// https://github.com/code-423n4/2021-06-gro/blob/main/contracts/pools/oracle/Buoy3Pool.sol#L25 contract Buoy3Pool is FixedStablecoins, Controllable, IBuoy, IChainPrice { ... mapping(uint256 => uint256) lastRatio;
function safetyCheck() external view override returns (bool) { for (uint256 i = 1; i < N_COINS; i++) { uint256 _ratio = curvePool.get_dy(int128(0), int128(i), getDecimal(0)); _ratio = abs(int256(_ratio - lastRatio[i])); if (_ratio.mul(PERCENTAGE_DECIMAL_FACTOR).div(CURVE_RATIO_DECIMALS_FACTOR) > BASIS_POINTS) { return false; } } return true; }
function _updateRatios(uint256 tolerance) private returns (bool) { ... for (uint256 i = 1; i < N_COINS; i++) { lastRatio[i] = newRatios[i];
Tools Used
Recommended Mitigation Steps
Double check if this situation can occur. Perhaps call _updateRatios as soon as possible. Or check in safetyCheck that the lastRatio values are initialized