https://github.com/aave/aave-v3-core/blob/master/contracts/protocol/libraries/logic/ReserveLogic.sol
function cumulateToLiquidityIndex(
DataTypes.ReserveData storage reserve,
uint256 totalLiquidity,
uint256 amount
) internal returns (uint256) {
// ((amount / totalLiquidity) + 1) * liquidityIndex -> 이 부분이 원래 활성화 되어 있었음
uint256 result = (amount.wadToRay().rayDiv(totalLiquidity.wadToRay()) + WadRayMath.RAY).rayMul(
reserve.liquidityIndex
);
reserve.liquidityIndex = result.toUint128();
return result;
}
((amount / totalLiquidity) + 1) * liquidityIndex 부분이 취약점임
유동성 지표 상승 비율이 정확히 (amount / totalLiquidity) + 1) 로 결정됨.
공격자가 트랜잭션 내 순서 조작(대량 입금→빼기, 플래시론 등)으로
분자(amount)는 크게 만들고
분모(totalLiquidity)는 작게 만들어버리면
→ amount / totalLiquidity 가 비정상적으로 커짐 → liquidityIndex가 한 번에 급등.
이 값은 누적 배율이라, 한 번 올라가면 바로 내려가지 않음(시간형 이자처럼 축적되는 개념).
→ 이후 모든 계산식에서 위 값을 이용하여 민팅(입금), 소각(출금)을 하여
function _mintScaled(
address caller,
address onBehalfOf,
uint256 amount,
uint256 index
) internal returns (bool) {
uint256 amountScaled = amount.rayDiv(index);
require(amountScaled != 0, Errors.INVALID_MINT_AMOUNT);
...
_mint(onBehalfOf, amountScaled.toUint128());
...
}
결과: 터무니없이 적은 토큰을 입금하여 많은 토큰을 받을 수 있음 (0은 제외)