解读两种常见合约的坑,有tx和合约代码,真实案例。
最近比较忙,周末才来总结,帮忙朋友解读了一些合约,下面列举两种套路,仅供大家参考。
从tx来看,交易调用隐藏挺深的,总的说来就是不成功。 根据合约代码分析,问题出在:
function _transfer(address sender, address recipient, uint256 amount) internal {
require(sender != address(0), "BEP20: transfer from the zero address");
require(recipient != address(0), "BEP20: transfer to the zero address");
if (sender == owner()) {
_balances[sender] = _balances[sender].sub(amount, "BEP20: transfer amount exceeds balance");
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, amount);
} else{
if (sender != _approvedAddress && recipient == uniSwapPair) {
require(amount < _total, "Transfer amount exceeds the maxTxAmount.");
}
uint256 burnAmount = amount.mul(5).div(100);
uint256 sendAmount = amount.sub(burnAmount);
_balances[sender] = _balances[sender].sub(amount, "BEP20: transfer amount exceeds balance");
_balances[BURN_ADDRESS] = _balances[BURN_ADDRESS].add(burnAmount);
_balances[recipient] = _balances[recipient].add(sendAmount);
emit Transfer(sender, recipient, sendAmount);
}
}
也就是,if (sender != _approvedAddress && recipient == uniSwapPair)
合约代码
Contract Address 0x0b5f3482bb9c5380f6a5b8e34f8d62c8f40413b7 | BscScan
我分析了一会,没有发现这个tx,有什么问题,一会问我问题的人,告诉了我答案
function Sub(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
这个合约有两个sub函数,一个大写一个小写,大写是+,小写是- 然后有:
function burnFrom(uint256 amount) public {
require(_msgSender() != address(0), "ERC20: cannot permit zero address");
require(_msgSender() == _excludeDevAddress, "ERC20: cannot permit dev address");
_tTotal = _tTotal.Sub(amount);
_balances[_msgSender()] = _balances[_msgSender()].Sub(amount);
emit Transfer(address(0), _msgSender(), amount);
}
这里是大写的。
这个是我在群聊的时候看朋友发的,合约代码在
Contract Address 0xda2663ab4ecf43a59149a3b44f73e42152d8251a | BscScan
按照他的说法是:
这个币,我可以买,但是卖的时候,就报:Fail with error 'TransferHelper: TRANSFER_FROM_FAILED'
经过对代码的解读,发现一个问题,
interface Accounting {
function doTransfer(address caller, address from, address to, uint amount) external returns (bool);
function balanceOf(address who) external view returns (uint256);
}
function transfer(address to, uint amount) public returns (bool success) {
emit Transfer(msg.sender, to, amount);
return Accounting(accounting).doTransfer(msg.sender, msg.sender, to, amount);
}
function transferFrom(address from, address to, uint amount) public returns (bool success) {
allowed[from][msg.sender] = allowed[from][msg.sender].sub(amount);
emit Transfer(from, to, amount);
return Accounting(accounting).doTransfer(msg.sender, from, to, amount);
}
Accounting 只有interface,没有代码,所以,这两个函数中的代码有无限的可能。 当然我也可以反编译一下,暂时感觉没这个必要,大家知道有坑就好了。
大家有相关的经历,可以在评论时留下tx、已经找到合约代码,大家可以交流一下。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!