背景介绍
在之前的一次应急响应中有客户反馈某合约在上X币交易所的时候,按照交易所的要求曾找人写了锁仓合约并完成了2.5亿某代币的锁仓操作,本来应该是三个月解锁一次,两年解锁完毕,然而一年快过去了,一笔解锁款都没有收到,客户感到很是费解,这和预期的有很大的差入,所以需要帮忙查看究竟是代码问题,还是操作问题并尽最大的可能将未解锁的合约代币进行解锁操作
锁仓合约
智能合约中的锁仓合约是一种功能强大的合约,它用于将加密货币或数字资产锁定在一个特定的账户中以实现一定的安全性和可控性,锁仓合约通常被用于以下几个方面:
- 基本锁仓:锁仓合约可用于将加密货币或数字资产锁定在一个特定的账户中一段预定的时间,这可以用于各种情况,例如:长期投资、团队解锁、ICO众筹等,在锁仓期间,资产将无法被转移或使用,直到锁仓期满
- 投票权锁定:一些项目或组织可能会使用锁仓合约来限制投资者或持有者的投票权以防止他们在短期内大量投票或操纵决策,在这种情况下锁仓合约可以将一定数量的代币或股份锁定在账户中直到特定的条件满足
- 奖励和激励计划:锁仓合约也可以用于奖励和激励计划,特别是在加密货币项目中,项目团队可以锁定一部分代币或股份以作为未来的奖励或激励分配给特定的个人或团队,这可以帮助确保项目的成功和可持续发展
- 安全保障:锁仓合约还可以用于提供额外的安全保障,通过将资产锁定在一个合约中可以防止黑客攻击或非法访问,这对于保护大量资产或敏感信息非常重要
分析过程
初次分析
第一次分析的时候客户提供了锁仓合约的代码,只是对锁仓解锁的业务逻辑进行了分析并没有彻底发现问题,基本的流程分析流程大致如下:
首先查看了合约代码,发现其中的锁仓部分代码中代币分配总量:2.5亿,耗费两年时间分配完成,其中每隔三个月解锁一次
contract xxxx is Ownable {
using SafeMath for uint256;
//Wallet Addresses for allocation
address public teamReserveWallet = 0xA;
address public finalReserveWallet = =0xA;
//Token Allocations
uint256 public teamReserveAllocation = 240 * (10 ** 6) * (10 ** 18);
uint256 public finalReserveAllocation = 10 * (10 ** 6) * (10 ** 18);
//Total Token Allocations
uint256 public totalAllocation = 250 * (10 ** 6) * (10 ** 18);
uint256 public teamTimeLock = 2 * 365 days;
uint256 public teamVestingStages = 8;
uint256 public finalReserveTimeLock = 2 * 365 days;
/** Reserve allocations */
mapping(address => uint256) public allocations;
/** When timeLocks are over (UNIX Timestamp) */
mapping(address => uint256) public timeLocks;
/** How many tokens each reserve wallet has claimed */
mapping(address => uint256) pub