address(reciver).transfer(amount);
token.transfer(reciver, amount);token.transferFrom(sender, reciver, amount);
//SPDX-License-Identifier: Unlicensepragma solidity ^0.8.0;import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";contract StokenERC20 is IERC20 { mapping(address => uint256) public override balanceOf; mapping(address => mapping(address => uint256)) public override allowance; uint256 public immutable override totalSupply; string public constant name = "STOKEN"; string public constant symbol = "SETH"; uint8 public constant decimals = 18; constructor(uint256 _totalSupply) { _totalSupply *= 10**18; totalSupply = _totalSupply; balanceOf[msg.sender] = _totalSupply; emit Transfer(address(0), msg.sender, _totalSupply); } function transfer(address _to, uint256 _value) public override returns (bool) { unchecked { if (balanceOf[msg.sender] >= _value && balanceOf[_to] + _value >= balanceOf[_to]) { balanceOf[msg.sender] -= _value; balanceOf[_to] += _value; emit Transfer(msg.sender, _to, _value); return true; } else { return false; } } } function transferFrom( address _from, address _to, uint256 _value ) public override returns (bool) { unchecked { if ( balanceOf[_from] >= _value && allowance[_from][msg.sender] >= _value && balanceOf[_to] + _value >= balanceOf[_to] ) { balanceOf[_to] += _value; balanceOf[_from] -= _value; emit Transfer(_from, _to, _value); allowance[_from][msg.sender] -= _value; emit Approval(_from, msg.sender, allowance[_from][msg.sender]); return true; } else { return false; } } } function approve(address _spender, uint256 _value) public override returns (bool) { allowance[msg.sender][_spender] = _value; emit Approval(msg.sender, _spender, _value); return true; }}/* Contract takes ERC20 Stokens as input and returns the native ETH (1:1 ratio).*/contract Exchange { IERC20 public token; address public owner; mapping(address => uint256) private balances; event Transfer(address indexed from, address indexed to, uint256 amount); event NativeTransfer(address indexed to, uint256 amount); constructor(address _token) payable { require(msg.value >= 10, "10 ETH required"); owner = msg.sender; token = IERC20(_token); } modifier onlyOwner() { require(msg.sender == owner, "not owner"); _; } function changeOwner(address _newOwner) public onlyOwner { owner = _newOwner; } function changeToken(address _newToken) public onlyOwner { token = IERC20(_newToken); } function balanceOf(address user) public view returns (uint256) { return balances[user]; } function enter(uint256 amount) public { require(amount >= 10 ether, "minimum is 10"); token.transferFrom(msg.sender, address(this), amount); balances[msg.sender] += amount; emit Transfer(msg.sender, address(this), amount); } function exit(uint256 amount) public { uint256 getAmount = balances[msg.sender]; require(getAmount >= amount, "user doesn't have enough funds deposited"); balances[msg.sender] -= amount; payable(msg.sender).transfer(amount); emit NativeTransfer(msg.sender, amount); }}
function transferFrom( address _from, address _to, uint256 _value ) public override returns (bool) { unchecked { if ( balanceOf[_from] >= _value && allowance[_from][msg.sender] >= _value && balanceOf[_to] + _value >= balanceOf[_to] ) { balanceOf[_to] += _value; balanceOf[_from] -= _value; emit Transfer(_from, _to, _value); allowance[_from][msg.sender] -= _value; emit Approval(_from, msg.sender, allowance[_from][msg.sender]); return true; } else { return false; } } } function enter(uint256 amount) public { require(amount >= 10 ether, "minimum is 10"); token.transferFrom(msg.sender, address(this), amount); balances[msg.sender] += amount; emit Transfer(msg.sender, address(this), amount); }
(bool success, bytes memory returnData) = targetContract.call(abi.encodeWithSignature("myFunction(uint256)", 123));if (success) { // 调用成功,处理返回值} else { // 调用失败,处理错误}
require(success, "failed!");
原文始发于微信公众号(SAINTSEC):以太坊应用中基于回退与返回错误的假充值攻击原理分析
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论