교육 목적으로만 제공되며 투자 조언이 아닙니다. 투자에는 손실이 발생할 수 있습니다.
핵심 답변
오라클 소수 자릿수 불일치는 컨트랙트가 원시 정수를 잘못된 단위 지수, 가격 방향 또는 내부 스케일로 해석할 때 발생합니다. 피드 소수 자릿수, 토큰 소수 자릿수, 호가 토큰 소수 자릿수, 래퍼 또는 지분의 교환율 스케일, 프로토콜의 WAD나 RAY 관행은 서로 독립적입니다. 프런트엔드 표시가 올바르게 보인다고 해서 소비자 컨트랙트가 같은 계산을 수행한다는 뜻은 아닙니다.
기준 토큰 원시 수량 A_raw의 소수 자릿수를 d_t, 기준 토큰 한 단위의 가격을 호가 토큰으로 나타내는 양의 피드 응답값 P_raw의 소수 자릿수를 d_p라고 하겠습니다. 소수 자릿수가 d_q인 호가 토큰 원시 수량은 V_raw = round(A_raw * P_raw * 10^d_q / 10^(d_t + d_p))입니다. 이 식은 명시한 호가 방향에만 유효하며 피드, 단위, 자료형 및 반올림 규칙을 검증해야 합니다. 어댑터가 이미 값을 정규화했다면 다시 스케일을 적용해서는 안 됩니다.
ERC-20의 decimals()는 선택적 표시 메타데이터이지 모든 토큰이 소수 18자리를 쓴다는 보장이 아닙니다. 피드의 decimals()는 해당 피드 응답값의 소수 자릿수를 나타내며 토큰이나 프로토콜 스케일을 나타내지 않습니다. 검사 산술은 오버플로 시 되돌리기로 중단할 수 있지만 차원이 잘못된 식은 감지하지 못합니다. 또한 중간 곱이 오버플로하면 최종값은 표현 가능하더라도 서비스 거부 상태가 생길 수 있습니다.
작동 방식
- 체인, 블록, 소비자 컨트랙트, 어댑터, 피드 프록시와 집계기, 토큰 또는 볼트, 컴파일러와 수학 라이브러리 버전 및 업그레이드 상태를 고정합니다.
- 모든 정수의 자료형과 단위를 목록화합니다. 토큰 원시 수량, 토큰 소수 자릿수, 부호 있는 피드 응답값, 피드 소수 자릿수, 기준 및 호가 방향, 래퍼 또는 지분 교환율, 프로토콜 내부 스케일, 출력 토큰 소수 자릿수를 포함합니다.
- 변환 전에 출처를 검증합니다. 올바른 주소와 방향, 양의 응답값, 타임스탬프와 상태, 허용 가능한 경과 시간과 범위, 대체 값의 의미, 필요한 경우 L2 시퀀서 유예 규칙을 확인합니다.
- 입력 원시 단위에서 출력 원시 단위로 이어지는 하나의 차원식으로 도출합니다. 스케일을 올리거나 내리는 경우를 명시적으로 분기하고, 모든 10의 거듭제곱 지수를 제한하며, 각 항을 정확히 한 번만 정규화합니다.
- 검증된 전정밀도 곱셈-나눗셈 또는 범위가 제한된 약분 방식을 사용합니다. 나눗셈 우선으로 인한 절삭, 검사되는 중간 곱의 오버플로, 검사되지 않은 순환, 안전하지 않은 부호 변환이나 좁은 자료형으로의 캐스팅을 피합니다.
- 경제 행위마다 내림, 올림 또는 최근접 반올림을 지정합니다. 담보, 부채, 차입, 발행, 상환, 수수료, 청산 및 볼트 지분 변환에는 서로 다른 보수적 방향이 필요할 수 있습니다.
- 극단적 수량, 소수 자릿수 조합, 역수, 복합 피드, 0, 음수 및 오래된 응답값, 업그레이드와 잔여 단위에 대해 골든 벡터와 속성 검사를 수행합니다. 온체인 결과를 독립적인 고정밀 모델과 대조하고 영향을 받을 수 있는 익스포저에 한도를 둡니다.
정규화는 표시 형식이 아니라 차원 분석입니다. BTC/USD와 USD/BTC에는 역수식이 필요하며 표지만 바꾼다고 가격이 뒤집히지 않습니다. 복합 피드에는 각 항의 스케일과 타임스탬프가 필요합니다. Solidity 정수 나눗셈은 0을 향해 절삭하므로 대수적으로 같은 식이라도 순서를 바꾸면 온체인 결과가 달라질 수 있습니다. 전정밀도 mulDiv는 중간값 비트 폭 문제를 해결하지만, 호출자는 여전히 올바른 분자, 분모, 단위, 한계 및 반올림 방향을 제공해야 합니다.
계산 예시
- 8자리와 18자리. BTC/USD 피드가
6,000,000,000,000을 반환하고 소수 자릿수가d_p = 8이면 가격은60,000 USD/BTC입니다. 원시 응답값을 소수 18자리로 해석하면0.000006 USD/BTC가 되어10^10배 과소평가되며, 이는10^9배가 아닙니다. 가격을 WAD로 변환하면6,000,000,000,000 * 10^(18 - 8) = 60,000,000,000,000,000,000,000입니다. - 수량, 가격 및 출력 단위.
A_raw = 2,500,000은2.5토큰을 나타내고 소수 자릿수는d_t = 6입니다.P_raw = 200,000,000은2호가 토큰을 나타내고 소수 자릿수는d_p = 8입니다. 소수 18자리 내부 호가값은2,500,000 * 200,000,000 * 10^18 / 10^(6 + 8) = 5,000,000,000,000,000,000, 즉5 quote tokens입니다. 토큰 분모를 빼면 포지션이10^6배 과대평가됩니다. - 역수와 절삭. WAD 스케일의 ETH/USD는
2,000 * 10^18입니다. 같은 스케일의 USD/ETH는floor(10^36 / (2,000 * 10^18)) = 500,000,000,000,000, 즉0.0005 ETH/USD입니다. 별도로A_raw = 999,999,d_t = 6, 가격이2 * 10^18이면 전정밀도 곱셈-나눗셈 결과는1,999,998,000,000,000,000입니다. 수량을 먼저10^6으로 나누면0이 되어 가치를 모두 잃습니다. - 중간 오버플로와 반올림.
x = 2^200,y = 2^100, 분모를2^100으로 둡니다. 정확한 결과2^200은uint256에 들어가지만x * y = 2^300은 들어가지 않습니다. 검사 곱셈은 되돌리고 비검사 곱셈은 순환하지만, 전정밀도mulDiv는2^200을 반환합니다. 정수5 / 2는 내림하면2, 올림하면3이므로 반올림 규칙은 경제적 불변조건의 일부입니다.
위험
- 체인, 피드, 프록시, 어댑터, 토큰, 볼트 또는 소비자 컨트랙트 주소가 잘못되었습니다.
- 역수 변환 없이 기준 자산과 호가 자산 방향을 뒤집습니다.
- 토큰 소수 자릿수를 18로 가정하거나 선택적 메타데이터를 읽을 수 없거나 잘못되어 있습니다.
- 피드에서 읽어 고정하지 않고 피드 소수 자릿수를 8로 가정합니다.
- 호가 토큰 소수 자릿수와 프로토콜 WAD, RAY, 시장 또는 회계 스케일을 혼동합니다.
- 래퍼, 지분, 지수 또는 교환율 소수 자릿수를 빠뜨립니다.
- 어댑터가 이미 정규화한 값에 스케일 인자를 두 번 적용합니다.
- 필요한 스케일 인자나 분모를 빠뜨립니다.
- 응답값이 양수인지 확인하기 전에 부호 있는 값을 부호 없는 자료형으로 변환합니다.
- 0, 오래된 값, 미완료 값, 상한에 걸린 값 또는 무효한 피드 결과를 받아들입니다.
- 소수 자릿수 지수나 10의 거듭제곱 계산이 언더플로, 오버플로 또는 한계 초과를 일으킵니다.
- 최종 몫은 범위 안에 들지만 곱셈 중간값이 오버플로합니다.
- 비검사 산술, 비트 시프트 또는 명시적 축소 변환이 조용히 순환하거나 절삭합니다.
- 곱셈 전 나눗셈이 정밀도를 없애거나 잔여 단위를 0으로 만듭니다.
- 경제 행위에 맞지 않는 내림, 올림 또는 최근접 반올림을 사용합니다.
- 반복 변환으로 정밀도 손실이나 체계적인 가치 누출이 누적됩니다.
- 가격, 상한, 비율, 백분율, 베이시스포인트, WAD 및 RAY 값을 서로 다른 단위로 비교합니다.
- 피드, 토큰, 프록시, 어댑터 또는 볼트 업그레이드로 저장된 소수 자릿수 가정이 무효화됩니다.
- 프런트엔드, 지갑, RPC 또는 인덱서 형식이 다른 온체인 계산을 가립니다.
- 오평가가 차입, 발행, 상환, 청산, 상한, 부실채권 또는 불공정한 지분 발행을 증폭합니다.
흔한 오해
- “모든 ERC-20 토큰은 소수 18자리를 사용한다.” ERC-20 메타데이터 메서드는 선택 사항이며 실제 자산은 서로 다른 값과 동작을 사용합니다.
- “모든 USD 가격 피드는 소수 8자리를 사용한다.” 피드 정밀도는 정확한 배포본의 인터페이스 속성이므로 직접 읽고 버전을 고정해야 합니다.
- “원시 정수가 크면 조작의 증거다.” 단위, 방향, 소수 자릿수, 타임스탬프 및 소비자 스케일이 없으면 원시 크기는 의미가 없습니다.
- “Solidity 0.8이면 스케일링도 정확해진다.” 검사 오버플로는 되돌릴 수 있지만 잘못된 단위, 절삭, 캐스팅 또는 반올림 정책을 고치지는 않습니다.
- “항상 먼저 곱하거나 소수 자릿수를 늘리면 정확도가 높아진다.” 오버플로, 이중 스케일링 또는 잘못된 단위 보존이 발생할 수 있습니다. 전정밀도 연산에도 올바른 식이 필요합니다.
관련 주제
출처
- Data Feeds API Reference - Chainlink Documentation (조회일: 2026-08-13)
- Chainlink Data Feeds - Chainlink Documentation (조회일: 2026-08-13)
- ERC-20: Token Standard - Ethereum Improvement Proposals (조회일: 2026-08-13)
- Types - Solidity Documentation (조회일: 2026-08-13)
- Expressions and Control Structures - Solidity Documentation (조회일: 2026-08-13)
- Utils - OpenZeppelin Contracts Documentation (조회일: 2026-08-13)
- Oracles - Aave Protocol Documentation (조회일: 2026-08-13)
- Compound v2 Price Feed - Compound Documentation (조회일: 2026-08-13)