Understanding Math-Heavy Code
三句話摘要
如何系統性地拆解與審計 Solidity 中複雜數學函數(以 Uniswap V3 tick 計算為例)。 審計複雜數學代碼的關鍵不是硬讀,而是先掌握公式、刷新相關代數知識,再用最簡單的測試案例逐步反推每個常數的來源,小步驗證直到理解整體演算法。 理解意圖先於閱讀代碼:Uniswap V3 tick 函數計算的是 `sqrt(1.001^tick) × 2^96`,若不先掌握這個公式就直接看代碼,會陷入細節迷宮而無法建立整體邏輯。
重點整理
重點- 1
理解意圖先於閱讀代碼:Uniswap V3 tick 函數計算的是 `sqrt(1.001^tick) × 2^96`,若不先掌握這個公式就直接看代碼,會陷入細節迷宮而無法建立整體邏輯。
- 2
定點數與 Q 數的本質相同:Solidity 沒有小數,所以將數值乘以 2^96 或 2^128 進行整數編碼;用 2 的次方作為 scaling factor 的原因是 bit shift 比除法更省 Gas。
- 3
用最簡單案例反推大常數:選 tick=0、tick=-1、tick=-3 等觸發最少 if 分支的路徑,代入公式算出預期答案,再與代碼中預先計算好的大常數比對,就能還原開發者的設計思路。
- 4
Square and Multiply 演算法:tick 的二進位表示決定哪幾個 if 分支觸發,每個分支對應一個預計算常數(`sqrt(1.001^(-2^k))`),多個分支相乘等同於指數相加,這正是「平方乘法」演算法的精髓。
實用技巧與重點
乾貨- 公式:`sqrt(1.001^tick) × 2^96`
- Scaling factor:Q96 = 2^96,Q128 = 2^128(內部計算用)
- Bit shift by 32:從 Q128 轉換到 Q96(等同除以 2^32)
- Bit shift by 128:乘法後縮放還原,防止 overflow
- 每次乘兩個 Q128 數需右移 128 bit,否則精度膨脹到 2^256 溢出
- 工具:Python `decimal` 庫(避免浮點精度誤差)
- 演算法名稱:Square and Multiply Algorithm
- 比特偵測技巧:`abs_tick & 0x1`、`& 0x2`、`& 0x4` ... 偵測各 bit 是否為 1
- AI 使用建議:詢問「這段代碼實作的是哪個演算法?」,多問幾個模型取得多樣答案,再自行查文獻
結論
結論“審計複雜數學代碼的關鍵不是硬讀,而是先掌握公式、刷新相關代數知識,再用最簡單的測試案例逐步反推每個常數的來源,小步驗證直到理解整體演算法。”
完整解析
詳細在 Solidity 的數學庫審計中,最常讓人望而生畏的是一大段充滿魔法常數與位元操作的代碼。Jeffrey 以 Uniswap V3 的 tick 數學函數為例,示範如何把這種「大怪物」拆成可逐步驗證的小問題。
首先,他強調理解「這段代碼要算什麼」遠比逐行追蹤執行邏輯更重要。Uniswap V3 的 tick 函數要計算的是 `sqrt(1.001^tick) × 2^96`——這個公式明確寫在代碼注釋裡。Solidity 沒有浮點數,所有小數都必須用定點數(Fixed Point)表示:乘以 10^18 是常見做法,但乘以 2 的次方(如 2^96、2^128)更節省 Gas,因為這樣可以用 bit shift 代替除法,此類數值稱為 Q 數(Q96、Q128)。
確認公式後,Jeffrey 提出「挑選智慧子目標」的策略:從觸發最少 if 分支的測試案例入手。tick=0 時,任何數的 0 次方為 1,`sqrt(1) × 2^96 = 2^96`,代碼應輸出此值;而代碼中的初始值 `1 × 2^128` 在最後右移 32 位後恰好等於 2^96,驗證成功。接著測試 tick=-1,abs_tick=1 只觸發第一個 if,將此分支的大常數代入 Python(使用 decimal 庫避免精度損失)計算 `sqrt(1.001^-1) × 2^128`,結果與常數吻合。再測 tick=-3(二進位 11),觸發前兩個 if,兩個常數相乘(並右移 128 bit 防止溢出),結果同樣符合 `sqrt(1.001^-3) × 2^128`。
為什麼兩個常數相乘能得到 tick=-3 的結果?這裡需要代數知識:`sqrt(A) × sqrt(B) = sqrt(A × B)`,而 `1.001^-1 × 1.001^-2 = 1.001^-3`,所以指數可以相加。這正是「平方乘法演算法(Square and Multiply Algorithm)」的原理——tick 的二進位表示決定哪些預計算常數要相乘,每個 bit 對應 `sqrt(1.001^(-2^k))`,組合相乘等同計算任意 tick 的平方根。
最後 Jeffrey 建議,可以把這段代碼丟給 AI 詢問「它實作的是哪個演算法」,多問幾個模型取得不同答案,再自行研究那個演算法並對應回代碼,比直接請 AI 解釋代碼更可靠(目前模型在數學代碼解釋上仍容易幻覺)。
關鍵時刻
Pipeline v2帶時間戳的重點,會在逐字稿層級分析上線後產生。目前請先透過原始影片觀看。
事實查核
Pipeline v2說法查證是下一次管線升級的一部分。KeyFrame 只會顯示它真正能驗證的內容。

