MOVE漏洞总结
Move 语言智能合约安全:10 个经典漏洞深度剖析Move 是一种专为资产安全和可信赖性而设计的编程语言,它的核心理念是通过其独特的**资源类型系统(Resource Type System)**来从根本上防止资产被复制、意外销毁或丢失。它在编译时强制执行这些规则,从而在很大程度上避免了许多传统区块链语言中常见的致命漏洞,比如代币重复发行或意外丢失。
然而,尽管 Move 提供了强大的安全保障,但合约的安全性最终还是取决于开发者的设计和实现。不正确的逻辑、对 Move 特性的误解或编程上的疏忽,仍然可能引入严重的漏洞。
本文件将对 Move 智能合约中 10 个常见且潜在的漏洞类型进行深度剖析,旨在帮助开发者更好地理解语言陷阱,并编写出更健壮、更安全的合约。
1. 资产权限管理不当 (Improper Capability Management)核心原理:
在 Move 中,能力 (Capability) 是一种特殊的资源类型,它代表了对特定操作的权限。这是一种强大的访问控制机制,例如,一个 AdminCap 资源可以授予持有者调用管理函数的权限。这种模式比依赖于硬编码的地址更安 ...
move 学习
move: 单个程序被组织成一个包包:Move.toml和源文件Move.toml: 关于包的元数据源文件:模块的源代码move语言中的,模块下的成员都是私有的
在开发过程包没有地址,需要将其设置为0x0
sui的地址是32字节
账户是有私钥生成,并且又地址标识的,账户可以拥有对象,并且可以发送交易,每一笔交易有一个发件人,并且发件人由地址标识
基础模块move中的模块的所有成员都是模块的私有成员
用 module关键字后跟包地址,模块名称,分号和模块的主体.
模块是定义类型的核心程序单元。
基础语法:
module <address>::<identifier> { (<use> | <type> | <function> | <constant>)*}
注释行注释: // 即被编译器忽略的
阻止注释:/* 开头,结尾 */ ,注释多行,块注释,注释调代码块
文档注释:用于为伪代码生成文档的特殊注释。///
基本 ...
Notional Exponent 审计
Notional Exponent审计报告迁移pool池的功能,把迁移数设置为了不可变量当 Convex 的某个奖励池被废弃(例如旧的 pid 失效),并为同一个LP token分配了新的 pid 时,升级管理员可以执行“迁移”操作,将流动性从旧 pid 提取,再存入新的 pid。
但是,策略合约中记录的 pid 是不可变(immutable)的。这意味着策略合约本身仍会引用旧的 pid 和旧的奖励池(即旧的 yieldToken),即使底层资产已经迁移到了新的奖励池。结果是:策略的内部状态与 Convex 实际奖励池状态不一致,功能失效。
迁移资金时,没有注意还有其他的资金在另外一个地方
这个要根据分析迁移时的资金转移来看,必须得深入每一个调用链的关系.分析资金的走向
AbstractRewardManager::migrateRewardPool 函数允许管理员将当前奖励池迁移至一个新的奖励池。
在迁移过程中,合约会尝试先领取旧奖励池的奖励,然后再将资产转入新奖励池。但在调用链深入分析后发现,这个流程 忽略了 Convex 中“奖励暂存合约(stash)”中的奖励领取机制,导致部 ...
GMX协议遭受重入攻击损失4200万美美金
背景在2025年7月9号,也就是前不久,GMX协议在Arbitrum上遭黑客攻击,攻击的主要问题集中在 重入+share price 操控
常见的攻击模式:在 deposit/mint 中重入,通过再次 deposit或者 donate 的形式,操控 share price 导致 withdraw/redeem 的时候 share 价格相对于 deposit/mint 过程发生变化。从而实现立马获取收益
在这个合约中,并不是这样简单的重入(如果这样,早就被盗窃完了),仔细看代码,其实是 GMX 协议本身依赖外部合约进行重入保护,但是外部合约对用户地址存在 callback,且没有使用安全的callback 形式,导致用户绕过了外部的重入开关后,直接对 share price 价格进行操控。从而获利。
关于OPE
OPE 讴谱讴谱目标:O-P-EO: Optimization-优化
优化一个新体系p: Purification-净化
除去恶方面E: Evolution-进化
提升和扩大体系功能
五共思想共识:学区块链的第一步就是了解比特币以太坊,比特币的共识是POW,由于少数人可以控制节点权力,到以太坊所使用的共识就改进为POS,而我现在正在研究Solana的底层协议,它又是采用POH共识,通过历史时间证明,加快了交易的执行,是性能的优化。所以共识就是在不断发展,不断优化,符合大部分人的利益所认同的所接受的。OPE中提供就是按贡献分配这个共识,我就觉得有点和比特币POW有点相似,你做有效事的越多,你就收获的越多。
共创:打破垄断,一起创作,合作。在OPE世界中,是优缺互补,一起发挥各自的价值做好一件事
共生:我感觉就是没有竞争,互惠共利,比如现在的外卖大战,以前的购物平台纷纷宣布投入外卖市场,各家都拿出最大的优惠来竞争,如果各家都能拿出自己的资源,共同友好发展,就能实现利益最大化,不就是达到了一个共生的理念。
共治:现在社会都是上级传达命令,我们需要去服从命令,在OPE中的逻辑强调的事议定和 ...
sherlock-S-locker System
sherlock-S-locker System升级合同,常量发生改变现有正式合约中的 DOWNSCALER 为 1e16,而提议升级的合约中 DOWNSCALER 为 1e18,两者不一致,导致以下影响:
升级合约后新加入的质押者,在 lockedStakedBalance 相同的情况下,所获得的单位数(units)明显少于老质押者,分配收益时不公平。
升级合约后,如果已有质押者追加较少(少于100倍)的质押金额,其单位数反而会减少,获得的税收分成变少。
质押者可能会提前操作,在合约升级前抢先质押,以获得更多单位数并获取更大的税收分成。
抢跑攻击,在知晓分配收益时,扩大自己的份额,获取更多的收益在解锁获得惩罚金时,攻击者提前知道,然后通过提供流动性或者质押金额,去分配获益
某个用户准备进行立即解锁(instant unlock)。
恶意的 Locker 拥有者在此之前增加自己的流动性或质押额度。
_instantUnlock 被调用,惩罚金被分配给当前的 LP 和质押者。
恶意 Locker 拥有者因持有单位(units)而获得部分惩罚金收益。
获取收益后,立即撤 ...
sherlock-DODO Cross-Chain DEX
sherlock-DODO Cross-Chain DEX参数没有校验,用户可以伪造ZEVM 合约中的 onCall() 函数接收来自Gateway的 token 和 amount,但没有验证解码后的 MixSwapParams 是否与这些值一致。
具体来说:
params.fromToken 完全由用户传入消息决定
params.fromTokenAmount 也是用户可控的
因此攻击者可以:
通过桥接发送一小笔任意代币(如 1 DAI)
在消息中伪造一个大额的 swap 请求,比如用合约中持有的大额WZETA来兑换 USDC
实际 swap 时使用的是合约自己持有的 WZETA
攻击者获得兑换后的 USDC,而合约的 WZETA 被盗
这会导致攻击者可以完全清空合约中持有的高价值代币。
参数没有校验如果发生转移的是原生代币,实际上是没有校验数量是不是准确的
function withdrawToNativeChain( address zrc20, uint256 amount, bytes calldata message) external payab ...
单机版区块链的实现
单机版区块链的实现全部代码都已开源在git上 hyblockchain
前置知识开始之前,首先要了解一些基础知识,这里简单的介绍一下
区块链的结构区块(Block)包含:区块头(Block Header):包含前一个区块哈希、Merkle 根、时间戳、随机数等交易列表(Transactions):每个区块中打包的所有交易链(Chain):每个区块通过 previousHash 指向前一个区块形成链
哈希函数作用:确保数据完整性、防篡改常用:SHA256(Bitcoin)、Keccak256(Ethereum)本实验使用的是SHA256
交易系统
交易结构(Transaction)
发送方地址、接收方地址、金额、签名(可选)
交易池(Mempool):待打包的交易集合
简单账户模型或UTXO模型
账户模型(如 Ethereum):记录每个地址的余额
UTXO 模型(如 Bitcoin):每个未花费输出作为新交易输入
状态树 MPT使用的是key,value来实现
叶子节点:实际存放值的节点分支节点:有16个子节点,用来指向多条路径扩展节点:存储公共前缀,它的下一节点只能是分 ...
sherlock-Usual ETH0
sherlock-Usual ETH0这是一个关于代币质押与兑换的合约
移除某些质押代币后,导致某些函数功能不能使用因为某些函数(swap等)利用的数组来实现历遍质押代币,有些条件判断了质押代币不能为零,如果某些代币被移除后,那么整个函数就会被revert.
精度的问题,四舍五入,向下取整,多层函数实现的向下取整后,又作为分母,导致差值越来越大建议给分母加一消除向下取整
function wadTokenAmountForPrice(uint256 wadStableAmount, uint256 wadPrice, uint8 tokenDecimals) internal pure returns (uint256){+ return Math.mulDiv(wadStableAmount, 10 ** tokenDecimals, wadPrice + 1, Math.Rounding.Floor);- return Math.mulDiv(wadStableAmount, 10 ** tokenDecimals, wadPrice, Ma ...
sherlock-LEND
sherlock-LEND这是一个关于跨链的借贷,那么漏洞点就是在跨链的处理上
高gas费用阻碍从边界用户退出质押原因就是使用数组记录数据,并且没有限制,导致gas线性增加,用户支付不了,退出质押代码漏洞
// 遍历数组确定相关层级变更区间 for (uint256 i = 0; i < userTierHistory.length; i++) { if (userTierHistory[i].timestamp <= fromTime) { currentTier = userTierHistory[i].to; relevantStartIndex = i; } else { break; } } // 计算区间内各层级的利息 for (uint256 i = relevantStartIndex + 1; i < userTierHistory.length; i++) { if (userT ...