8BTCCI: 14768.96 -3.85% 8BTCVI: 7949.68 -7.19% 24H成交额: ¥4836.64亿 +0.19% 总市值: ¥19559.26亿 -3.47%
Cosmos安全漏洞解析:21天锁仓资金可提前赎回?

Cosmos安全漏洞解析:21天锁仓资金可提前赎回?

PeckShield 发布在 海盗号 61926



今晨,Cosmos 团队表示在 Cosmos SDK 发现严重安全漏洞。PeckShield 安全人员分析发现,原本 Cosmos 抵押之后需要等待 21 天才能赎回,但合约代码里 Validator 状态变化时存在一种逻辑缺陷,使得用户可以减少 21 天固定赎回时间,从而提前赎回抵押的数字资产,进而破坏原本的 POS 共识可更短周期使用资金进行重复抵押赚取利息。



Cosmos 简介



Cosmos 是最新上线的基于 Tendermint 共识的区块链网络,提出 IBC 通迅协议,用于解决资产跨链的问题,其核心主链被称为 Cosmos Hub,号称『万链之王』。其上的平台代币为 Atom,用户通过验证者投票参与服务治理与维护,同时接收系统激励,史称『 Staking 模式』,为 2019 年区块链明星项目之一。



验证者 Validator



  1. Cosmos Hub 是基于 Tendermint,它依靠一组验证者来保护网络,等同于 Bitcoin、Ethereum 等 PoW 网络中的矿工角色 ⛏️;

  2. 验证者运行一个完整的 Cosmos 节点,并通过广播包含由其私钥签署的加密投票参与共识,有一定的硬件投入成本;

  3. 验证者需要抵押定额的 Atom 作为保证金,且系统只有股权最高的 100 个节点会成为验证者;

  4. 验证者在区块链中打包交易提交新块并获得系统激励,这是验证者的收入,等同于挖矿收益;

  5. 另外,验证者在参与治理方面,他们还必须对网络中的提案进行投票,只有投票通过的提案才能发挥效应(例如这次事件的代码更改8号提案),投票权重根据每一位验证者存放的总权益进行加权;

  6. 安全稳定的验证者会产生稳定的收益,有问题的节点导致您损失本金,例如验证者节点掉线会损失 0.01% 本金。


由此可知,运行一个 Validator 角色的难度不低于开一个 PoW 矿池,普通用户要想加入 Cosmos 主网,并获取收益是个门槛比较高的事情。

委托人 Delegator


由于普通用户持币但又不参与委托的人,手中的 Atom 会面临增发而贬值,但是直接参与 Cosmos 主网有一定的技术难度,因此出现了委托人 Delegator 角色。委托人是那些不能或不想自己运行验证节点的 Atom 持有者,普通用户可以将 Atom 委托给验证人并获得部分收入,例如星火矿池提供的委托服务。


用户一旦赎回委托订单,Cosmos 将在赎回操作 21 天之后将委托抵押的 Atom 退回给委托人。


因此这 21 天为平台固定的锁仓时间,如果出现一种情况,Cosmos 系统存在设计缺陷,导致委托人的赎回周期可变,这对平台上的其它用户(委托人和验证者)来说,是不公平的,也破坏了 Cosmos 区块链的共识机制。

验证者状态机


在了解这个漏洞之前,我们先来看下 Cosmos 网络之上的验证者状态变化图:



其中,一共有三个状态:


  • bonded

  • unbonded

  • unbonding


状态之间的变化关系如下:



  1. 验证者默认属于 unbonded 状态,当发起 bondValidator 之后,状态变更为 bonded


    变更这一状态状态之后,验证都开始接收系统收益;




  2. 而当验证者发起 beginUnbondingValidator 以退出 bonded 状态时,其状态变更为 unbonding


    同时系统不再给这一验证者发送任何收益,同时这一验证者的委托人可以发起赎回操作;




  3. 若委托人没有发起赎回操作,那么处于 unbonding 状态的验证者可以重新 bondValidator 回到 bonded 状态以接收系统收益;




  4. 处于 unbonding 状态的验证者,当用户赎回时间 21 天到期之后,将进入到 unbonded 状态,此时委托者接收到之前抵押的 Atom 及抵押期间的收益。




21 天锁仓期


上面我们了解到验证者在帮助抵押赎回方面的整体流程,表面上没有什么问题,PeckShield 安全人员在分析 Cosmos SDK 代码的时候,发现了这一赎回流程中的致命设计缺陷,可导致委托者利用验证者 unbonding 状态,突破 21 天锁仓固定期而提前赎回。


我们先看旧版的赎回代码:



其大体流程如下,


  1. 获取验证者unbonding 完成时间(对应真实的锁仓到期时间)和区块高度;

  2. 将待赎回部分代币根据锁仓到期时间和区块高度生成一个锁币赎回记录;

  3. 将这一赎回记录保存到队列之中,等待时间到期之后,退还锁币资金给委托人。


细心的用户发现了这里的问题,一图以盖之:



简而言之,系统在计算锁仓到期时间的时候,误用 Validator 开始 unbond 状态时间和 Delegator 赎回发起时间,使得 Delegator 可以使用这一时间差赠取差异:


  1. Validator 正常发起 beginUnbondingValidator 操作;

  2. DelegatorValidator 发起 unbond 操作之后 7 天时发起 Undelgate 赎回操作,理论上赎回时间为 21 天,但是这里计算的时候使用的是 Validator 发起 unbond 操作的时间,因此,这一个 Deletagor 『免费』缩减了 7 天的赎回时间,再经过 14 天时间就可以收到锁仓的资金。


此时,我们再来看修复之后的代码:



此时,无论 Delegator 何时发起 Undelgate 操作,都会确保从发起开始计算 21 天,而与验证者无关。

小结


Staking 作为 2019 年新潮的区块链项目,获取了一定的瞩目,无论你是 Staking 的项目方,还是参与 Staking 的验证者及普通用户,在资产面前,我们都应该保有敬畏之心。


文章标签: COSMOS
评论
登录 账号发表你的看法,还没有账号?立即免费 注册