当前位置: 首页 > news >正文

网站默认图片素材网站服务器空间选择

网站默认图片素材,网站服务器空间选择,wordpress主题和模板,名雕装饰Solidity 合约安全#xff0c;常见漏洞#xff08;第三篇#xff09; ERC20 代币问题 如果你只处理受信任的 ERC20 代币#xff0c;这些问题大多不适用。然而#xff0c;当与任意的或部分不受信任的 ERC20 代币交互时#xff0c;就有一些需要注意的地方。 ERC20#…Solidity 合约安全常见漏洞第三篇 ERC20 代币问题 如果你只处理受信任的 ERC20 代币这些问题大多不适用。然而当与任意的或部分不受信任的 ERC20 代币交互时就有一些需要注意的地方。 ERC20转账扣费 当与不信任的代币打交道时你不应该认为你的余额一定会增加那么多。一个 ERC20 代币有可能这样实现它的转账函数如下所示 contract ERC20 {// internally called by transfer() and transferFrom()// balance and approval checks happen in the callerfunction _transfer(address from, address to, uint256 amount) internal returns (bool) {fee amount * 100 / 99;balanceOf[from] - to;balanceOf[to] (amount - fee);balanceOf[TREASURY] fee;emit Transfer(msg.sender, to, (amount - fee));return true;} }这种代币对每笔交易都会征收 1%的税。因此如果一个智能合约与该代币进行如下交互我们将得到意想不到的回退或资产被盗。 contract Stake {mapping(address uint256) public balancesInContract;function stake(uint256 amount) public {token.transferFrom(msg.sender, address(this), amount);balancesInContract[msg.sender] amount; // 这是错误的}function unstake() public {uint256 toSend balancesInContract[msg.sender];delete balancesInContract[msg.sender];// this could revert because toSend is 1% greater than// the amount in the contract. Otherwise, 1% will be stolen// from other depositors.token.transfer(msg.sender, toSend);} }ERC20: rebase 的代币 Rebasing 代币由 Olympus DAO 的 sOhm 代币 和 Ampleforth 的 AMPL 代币所推广。Coingecko 维护了一个 Rebasing ERC20 代币的列表。 当一个代币回溯时总发行量会发生变化每个人的余额会根据回溯的方向而增加或减少。 在处理 rebase 代币时以下代码可能会被破坏 contract WillBreak {mapping(address uint256) public balanceHeld;IERC20 private rebasingTokenfunction deposit(uint256 amount) external {balanceHeld[msg.sender] amount;rebasingToken.transferFrom(msg.sender, address(this), amount);}function withdraw() external {amount balanceHeld[msg.sender];delete balanceHeld[msg.sender];// 错误, amount 也许会超出转出范围rebasingToken.transfer(msg.sender, amount);} }许多合约的解决方案是简单地不允许 rebase 代币。然而我们可以修改上面的代码在将账户余额转给接受者之前检查 balanceOf(address(this))。那么即使余额发生变化它仍然可以工作。 ERC20: ERC777 在 ERC20 上的包裹 ERC20如果按照标准实现ERC20 代币没有转账钩子hook因此 transfer 和 transferFrom 不会有重入问题。 带有转账钩子的代币有应用优势这就是为什么所有的 NFT 标准都实现了它们以及为什么 ERC777 被最终确定。然而这已经引起了足够的混乱以至于 Openzeppelin 废止了 ERC777 库。 如果你只想让你的协议与那些行为像 ERC20 代币但有转账 hook 的代币兼容那么这只是一个简单的问题把 transfer 和 transferFrom 函数当作它们会向接收者进行一个函数调用即可。 这种 ERC777 的重入发生在 Uniswap 身上如果你好奇Openzeppelin 在这里记录了这个漏洞。 ERC20: 不是所有的 ERC20 代币转账都会返回 true ERC20 规范规定ERC20 代币在转账成功时必须返回 true。因为大多数 ERC20 的实现不可能失败除非授权不足或转账的金额太多大多数开发者已经习惯于忽略 ERC20 代币的返回值并假设一个失败的 trasfer 将被回退。 坦率地说如果你只与一个你知道其行为的受信任的 ERC20 代币打交道这并不重要。但在处理任意的 ERC20 代币时必须考虑到这种行为上的差异。 在许多合约中都有一个隐含的期望即失败的转账应该总是回退而不是返回错误因为大多数 ERC20 代币没有返回错误的机制所以这导致了很多混乱。 使这个问题更加复杂的是一些 ERC20 代币并不遵循返回 true 的协议特别是 Tether。一些代币在转账失败后会回退这将导致回退的结果冒泡到调用者。因此一些库包裹了 ERC20 代币的转账调用以回退恢复并返回一个布尔值。下面是一些实现方法 参考Openzeppelin SafeTransfer 及 Solady SafeTransfer 大大地提高了 Gas 效率 ERC20: 地址投毒 这不是一个智能合约的漏洞但为了完整起见我们在这里提到它。 转账零代币是 ERC20 规范所允许的。这可能会导致前端应用程序的混乱并可能欺骗用户让他们错误的以为他们最近将代币发送给了某地址。Metamask在这个线程中有更多关于这个问题的内容。 ERC20: 查看代码规避跑路 (在 web3 术语中“rugged意味着’跑路”, 直译是从你脚下拉出地毯 。) 没有什么能阻止有人在 ERC20 代币上添加函数让他们随意创建、转账和销毁代币–或自毁或升级。所以从根本上说ERC20 代币的 “无需信任” 程度是有限制的。 借贷协议中的逻辑错误 当考虑到基于 DeFi 协议的借贷如何被破坏时考虑在软件层面传播的 bug 并影响商业逻辑层面是很有帮助的。形成和完成一个债券合约有很多步骤。这里有一些需要考虑的攻击向量。 贷款人损失的方式 使到期本金减少可能为零而不进行任何支付的漏洞。当贷款没有偿还或抵押物降到阈值以下时买方的抵押物不能被清算。如果协议有一个转移债务所有权的机制这可能是一个从贷款人那里偷取债券的方式。贷款本金或付款的到期日被不适当地移到以后的日期。 借款人损失的方式 偿还本金时没有减少本金债务的 bug。一个 bug 或 gas 攻击使用户无法进行支付。本金或利率被非法提高。预言机的操纵导致抵押物贬值。贷款本金或付款的到期日被不适当地移到一个较早的日期。 如果抵押品从协议中被抽走那么贷款人和借款人都会损失因为借款人没有动力去偿还贷款而借款人则会损失本金。 正如上面所看到的DeFi 协议被 黑 的范围比从协议中抽走一堆钱通常成为新闻的那类事件要多得多。 抵押staking协议中的漏洞 成为新闻的那种黑客是抵押协议被黑掉数百万美元但这并不是唯一要面对的问题抵押协议可能面临的问题有 奖励能否延迟支付或过早地被索取奖励能否被不适当地减少或增加在更糟糕的情况下能否阻止用户获得任何奖励人们能否索取不属于他们的本金或奖励在最坏的情况下会耗尽协议所有资金存放的资产会不会被卡在协议中部分或全部或被不适当地延迟提取相反如果质押需要时间承诺用户是否可以在承诺时间之前提取如果支付的是不同的资产或货币其价值是否可以在相关的智能合约范围内被操纵如果协议 mint 自己的代币来奖励流动性提供者或质押者这一点是相关的。如果存在预期和披露出的本金损失的风险因素这种风险是否可以被不适当地操纵协议的关键参数是否有管理、中心化或治理风险 需要关注的关键是代码中涉及 资金退出 部分的代码。 还有一个 资金入口 的漏洞也要寻找。 有权参与协议中的资产抵押的用户能否被不适当地阻止 用户收到的奖励有一个隐含的风险回报和一个预期的资金时间价值。明确这些假设是什么以及协议会怎样偏离预期是很有帮助的。 未检查的返回值 有两种方法来调用外部智能合约1用接口定义调用函数2使用.call 方法。如下图所示 contract A {uint256 public x;function setx(uint256 _x) external {require(_x 10, x must be bigger than 10);x _x;} }interface IA {function setx(uint256 _x) external; }contract B {function setXV1(IA a, uint256 _x) external {a.setx(_x);}function setXV2(address a, uint256 _x) external {(bool success, ) a.call(abi.encodeWithSignature(setx(uint256), _x));// success is not checked!} }在合约 B 中如果 _x 小于 10setXV2 会默默地失败。当一个函数通过.call 方法被调用时被调用者可以回退但父函数不会回退。必须检查返回成功的值并且代码行为必须相应地分支。 msg.value 在一个循环中 在循环中使用 msg.value 是很危险的因为这可能会让发起者 重复使用 msg.value。 这种情况可能会出现在 payable 的 multicalls 中。Multicalls 使用户能够提交一个交易列表以避免重复支付 21,000 的 Gas 交易费。然而msg.value 在通过函数循环执行时被 “重复使用”有可能使用户双花。 这就是Opyn Hack的根本原因。 私有变量 私有变量在区块链上仍然是可见的所以敏感信息不应该被存储在那里。如果它们不能被访问验证者如何能够处理取决于其值的交易私有变量不能从外部的 Solidity 合约中读取但它们可以使用以太坊客户端在链外读取。 要读取一个变量你需要知道它的存储槽。在下面的例子中myPrivateVar 的存储槽是 0。 // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract PrivateVarExample {uint256 private myPrivateVar;constructor(uint256 _initialValue) {myPrivateVar _initialValue;} }下面是读取已部署的智能合约的私有变量的 javascript 代码 const Web3 require(web3); const PRIVATE_VAR_EXAMPLE_ADDRESS 0x123...; // Replace with your contract addressasync function readPrivateVar() {const web3 new Web3(http://localhost:8545); // Replace with your providers URL// Read storage slot 0 (where myPrivateVar is stored)const storageSlot 0;const privateVarValue await web3.eth.getStorageAt(PRIVATE_VAR_EXAMPLE_ADDRESS,storageSlot);console.log(Value of private variable myPrivateVar:,web3.utils.hexToNumberString(privateVarValue)); }readPrivateVar();不安全的代理调用 委托调用Delegatecall不应该被用于不受信任的合约因为它把所有的控制权都交给了委托接受者。在这个例子中不受信任的合约偷走了合约中所有的以太币。 contract UntrustedDelegateCall {constructor() payable {require(msg.value 1 ether);}function doDelegateCall(address _delegate, bytes calldata data) public {(bool ok, ) _delegate.delegatecall(data);require(ok, delegatecall failed);}}contract StealEther {function steal() public {// you could also selfdestruct here// if you really wanted to be mean(bool ok,) tx.origin.call{value: address(this).balance}();require(ok);}function attack(address victim) public {UntrustedDelegateCall(victim).doDelegateCall(address(this),abi.encodeWithSignature(steal()));} }升级与代理有关的 bug 我们无法在一个章节中对这个话题进行公正的解释。大多数升级错误通常可以通过使用 Openzeppelin 的hardhat 插件和阅读它所保护的问题来避免出错。 作为一个快速的总结以下是与智能合约升级有关的问题 自毁self-destruct和委托调用delegatecall不应该在执行合约中使用。必须注意在升级过程中存储变量不能相互覆盖在执行合约中应避免调用外部库因为不可能预测它们会如何影响存储访问。部署者决不能忽视调用初始化函数在基类合约中没有包括间隙gap变量以防止在基类合约中加入新的变量时发生存储碰撞这由 hardhat 插件自动处理。不可变immutable变量中的值在升级时不会被保留非常不鼓励在构造函数中做任何事情因为未来的升级必须执行相同的构造函数逻辑以保持兼容性。
http://www.hkea.cn/news/14383281/

相关文章:

  • 邢台专业网站建设源码吸引客流的25个技巧
  • 博物馆 网站 建设教你如何做网站
  • 杭州h5模板建站葫芦岛市网站建设
  • 视频网站直播如何做乐清网站设计制作
  • 怎么建网站 做app软件wordpress文章底部
  • 我要招人在哪个网站招合肥高端网站建设设计公司哪家好
  • 自己做网站能赚钱吗wordpress登录攻击
  • 建设百度网站怎么用ftp修改网站图片
  • 零起飞网站建设工作室注册功能网站建设
  • 高端企业网站建设规定品牌推广策划公司
  • 网站建设费 大创山西设计网站建设
  • 在线查询网站开发语言服务平台管理系统
  • 重庆璧山网站制作公司电话c 网站开发 调试
  • 网站优化排名方案成都园林景观设计公司推荐
  • wordpress 发布服务器南宁有名的seo费用
  • 网站如何做伪静态500元做网站
  • 网站推广内容朋友圈自己做的网站
  • 营销型网站搭建的工作百度收录自适应网站
  • 【网站建设网站如何被百度收入
  • 顺企网赣州网站建设国外建筑设计网站
  • vs做的本地网站上海网站哪家好
  • 普通展示型网站网站云主机吗
  • j2ee大型网站开发框架wordpress默认账号密码
  • 儿童玩具网站建设策划书百度一下官方网
  • 十堰网站建设兼职惠州seo推广公司
  • 制作游戏的网站网站建设平台信息
  • 望城区建设局网站企业网站建设小技巧有哪些
  • 百度推广要不要建网站如何自己建设简单的手机网站首页
  • 做淘客网站怎么样wordpress cloudflare
  • 重庆市建设局网站网盟推广合作