, description ); return newProposal.id; }
通过分析代码,可以发现在发起提案时,需要提案发起人拥有一定额度的票权利,这个值必须大于 proposalThreshold 计算得来的值,具体代码如下: function proposalThreshold() public view returns (uint256) { return SafeMath.div(yam.initSupply(), 100); } // 1% of YAM 也就是说提案发起人的票权必须大于 initSupply 的 1% 才能发起提案。那 initSupply 受什么影响呢?答案是 YAM 代币的 mint 函数,代码如下: * function mint(address to, uint256 amount) external onlyMinter returns (bool) { _mint(to, amount); return true; } function_mint(address to, uint256 amount) internal { // increase totalSupply totalSupply = totalSupply.add(amount); // get underlying value uint256 yamValue = amount.mul(internalDecimals).div(yamsScalingFactor); // increase initSupply initSupply = initSupply.add(yamValue); // make sure the mint didnt push maxScalingFactor too low require(yamsScalingFactor <=_maxScalingFactor(), "max scaling factor too low"); // add balance _yamBalances[to] =_yamBalances[to].add(yamValue); // add delegates to the minter _moveDelegates(address(0),_delegates[to], yamValue); emit Mint(to, amount); } 从代码可知,mint 函数在每次铸币时都会更新 initSupply 的值,而这个值是根据 amount 的值来计算的,也就是铸币的数量。 现在,我们已经分析完所有的流程了,剩下的就是把所有的分析串起来,看看这次的漏洞对 YAM 产生了什么影响,对上文的流程图做拓展,变成下面这样:
整个事件的分析如上图,由于 rebase 的时候取的是上一次的 totalSupply 的值,所以计算错误的 totalSupply 的值并不会立即通过 mint 作用到 initSupply 上,所以在下一次 (责任编辑:admin1) |