Transient Storage Vulns in Solidity
字数 1847 2025-08-29 08:30:12
Solidity Transient Storage 漏洞分析与实战教学
1. Transient Storage 概述
1.1 基本概念
Transient Storage 是 Solidity 0.8.24 版本引入的新特性,通过 EIP-1153 提案实现。它提供了:
- 第四种数据存储位置(区别于 memory、storage、calldata)
- 键值对存储方式
- 仅在同一个交易中有效,交易结束时自动清零
- 比常规 storage 更低的 gas 消耗
1.2 技术实现
Solidity 通过两个新的字节码支持 Transient Storage:
TSTORE- 存储数据TLOAD- 加载数据
在 Solidity 0.8.28 版本中,进一步引入了 transient 关键字,使开发者无需使用汇编即可方便地使用 Transient Storage。
2. Transient Storage 的安全风险
2.1 跨交易不可组合性
Transient Storage 只在单个交易内保持状态,这会导致跨交易调用时出现非预期行为。
示例问题:
// 使用 Transient Storage 的乘法器
function setMultiplier(uint x) { /* 使用 TSTORE 存储 */ }
function multiply(uint y) returns (uint) { /* 使用 TLOAD 读取并计算 */ }
连续三个交易:
setMultiplier(42)multiply(1)→ 返回 42multiply(2)→ 返回 0(非预期的 84)
2.2 恶意组合复用风险
在同一交易内,Transient Storage 变量会跨函数调用保持,可能导致:
- 变量被多次重复利用
- 外部调用后变量状态被恶意操控
官方建议:
建议在智能合约调用结束时完全清除 Transient Storage 变量,以避免此类问题,并简化复杂交易中合约行为的分析。
3. 实战案例:RemedyCTF 2025 tokemak
3.1 题目概述
目标:耗尽 LFGStaker 合约中的初始资产
合约功能:
- 用户质押 autoETH(类似 LP token)到 LFGStaker 合约
- 用户获得收益
- 提供 deposit 和 redeem 功能
3.2 漏洞分析路径
-
检查资产转换精度:
- 确认 deposit/redeem 中 assets 和 shares 的转换是否存在精度套利
- 本例中无套利机会
-
分析 totalAssets():
- 调用
autoETH.previewRedeem() - 该函数内部有复杂调用链,最终会:
- 检查闲置资金
- 不足时从流动性池(DestVault)取出
- 将取出的代币交换为所需资产
- 返回给用户并销毁 LP token
- 调用
-
关键漏洞点:
- 交换步骤允许用户指定任意汇率的池子
- 影响
totalAssets()返回值 - 使用 Transient Storage 决定是否使用用户指定池子
3.3 攻击步骤
-
初始资金获取:
- 使用闪电贷(如 Aave 或 dYdX)借入大量资金
-
Transient Storage 操控:
- 通过
AutopilotRouter.redeemWithRoutes()设置customRoutes - 该函数会:
initTransientSwap设置路由- 调用
vault.redeem(vault 为用户控制) exitTransientSwap清除状态
- 攻击方法:
- 传入自定义 vault 合约
- 在
vault.redeem中执行攻击代码 - 此时 Transient Storage 变量仍有效
- 通过
-
套利执行:
- 通过恶意池子操纵资产估值
- 调整 deposit/redeem 参数进行多轮套利
4. 防御建议
-
Transient Storage 使用规范:
- 始终在函数结束时清除 Transient 变量
- 避免在设置 Transient 变量后调用外部合约
-
安全模式:
function operation() external { // 设置 Transient 变量 transientVar = x; // 执行操作 _internalOperation(); // 清除 Transient 变量 delete transientVar; } function _internalOperation() internal { // 不包含外部调用 // ... } -
合约设计建议:
- 限制用户传入的合约地址权限
- 对关键操作添加重入保护
- 对 Transient Storage 的使用进行严格审计
5. 总结
Transient Storage 为 Solidity 提供了高效的临时存储方案,但也引入了新的安全考虑:
- 必须理解其生命周期(单交易有效)
- 警惕跨函数调用的状态保持
- 特别注意外部调用时的状态操控风险
- 遵循"设置-使用-清除"的最佳实践
通过 tokemak 案例可以看出,即使是简单的存储功能,在组合调用和外部合约交互的复杂场景下,也可能导致严重的安全漏洞。开发者需要全面理解这些新特性的行为特性,才能编写出安全的智能合约。