Popsicle攻击事件复盘分析 | 零时科技

2023-11-04 03:20

本文主要是介绍Popsicle攻击事件复盘分析 | 零时科技,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

事件背景

Popsicle Finance是专注于自动做市(AMM)流动性提供商(LP)的下一代跨链收益提高平台。旨在成为一个完全分散的平台,由其用户(ICE治理令牌的持有者)管理。ICE令牌将用于对协议更新,资产池包含,费用管理以及协议其他关键运营方面的提案进行投票。

零时科技区块链安全情报平台监控到消息,北京时间2021年8月4日,Popsicle Finance官方推文称Sorbetto Fragola被攻击,零时科技安全团队及时对该安全事件进行复盘分析。

事件分析

攻击信息

通过初步追踪分析,攻击者创建了3个攻击合约,进行了1笔攻击交易,共盗取资金价值超2100万美元,攻击信息如下:

攻击者钱包地址:

https://cn.etherscan.com/address/0xf9E3D08196F76f5078882d98941b71C0884BEa52

攻击者合约地址:

合约1:

https://cn.etherscan.com/address/0xdFb6faB7f4bc9512d5620e679E90D1C91C4EAdE6

合约2:

https://cn.etherscan.com/address/0x576cf5f8ba98e1643a2c93103881d8356c3550cf

合约3:

https://cn.etherscan.com/address/0xd282f740bb0ff5d9e0a861df024fcbd3c0bd0dc8

攻击交易:

https://cn.etherscan.com/tx/0xcd7dae143a4c0223349c16237ce4cd7696b1638d116a72755231ede872ab70fc

SorbettoFragola合约地址:

https://cn.etherscan.com/address/0xc4ff55a4329f84f9Bf0F5619998aB570481EBB48#contracts

攻击过程

攻击者在一笔交易中,利用同一攻击手法进行了多次获利,下面分步解析该笔交易,方便读者更清晰的了解攻击过程。

第一步:攻击合约1从Aave利用闪电贷借出3000万枚USDT,1.3万枚ETH,1400枚BTC,3000万枚USDC,300万枚DAI,20万枚UNI。

第二步:攻击者合约1通过Uniswap V3协议使用5492枚WETH和3000枚USDT添加流动性并获取10.52枚Popsicle LP。

第三步:攻击者合约1将获取的10.52枚Popsicle LP发送至攻击者合约2,后者又将LP发送至攻击者合约3,最后将LP归还至攻击者合约1。

第四步:攻击者合约1归还获取10.52枚Popsicle LP,得到添加流动性的5492枚WETH和3000枚USDT。

第五步:攻击者合约2和合约3分别从Uniswap V3优化器SorbettoFragola得到392枚ETH和215万枚USDT(凭空获利)。

交易信息中,攻击中循环执行8次同样的攻击(第二步至第五步)。

第六步:攻击者合约2和合约3将获取到的资金全部转至攻击者合约1。

第七步:攻击者归还闪电贷的3000万枚USDT,1.3万枚ETH,1400枚BTC,3000万枚USDC,300万枚DAI,20万枚UNI及其手续费。

第八步:攻击者将获取的资金统一转至攻击者钱包。

至此

攻击者通过该笔攻击交易获取了497万枚USDT,2560枚ETH,96枚BTC,538万枚USDC,16万枚DAI,1万枚UNI,总价值超过2100万美元。

走到这里大家可能会有疑问,交易的第三步为什么将LP多次转移,交易第五步为何会获取大量代币,下面我们从合约中分析SorbettoFragola合约代码逻辑。

攻击成功的原因

通过以上交易分析可以明确,攻击者将LP在攻击合约2和攻击合约3中转移后,这两个攻击合约就分别获取了大量资金,我们从交易logs信息中可查找出具体调用的合约调用事件,如下图:

从上图的信息我们可以发现,攻击者合约2触发了两次RewardPaid事件,分别是有LP时的触发和最后将LP转移走后的触发,但两次事件显示传入方法的参数截然不同,第一次为0,第二次为获利资金,我们继续分析RewardPaid事件对应的合约中collectFees方法,如下图:

上图collectFees方法中,RewardPaid事件触发需要进行三个主要判断:

  1. 修饰符执行updateVault(msg.sender);
  2. 判断奖励user.token0Rewards >= amount0;
  3. 判断(balance0 >= amount0 && balance1 >= amount1);

这里条件二是由updateVault(msg.sender)更新得到,只要获取的amount数值不超过奖励数值,均可完成该条件;条件三只要amount不超过对应合约余额,则该条件成立;下面继续分析条件一:修饰符updateVault(msg.sender),如下图:

调用_updateFeesReward方法,继续跟进,如下图:

上图updateFeesReward方法中,调用的第一个方法为pool.positionLiquidity,主要判断流动性是否为0,这里不做详细解释,我们主要来看获取奖励user.token0Rewards和user.token1Rewards变量相关联的四个方法:earnFees,tokenPerShare,fee0Earned,fee1Earned。

_earnFees方法,主要功能是获取Uniswap pool中的奖励数值,如下图:

_tokenPerShare方法,主要功能是通过earnFees方法中获取的奖励值来计算每个 LP 代币提供了多少代币,如下图:

fee0Earned,fee1Earned方法中,通过每个LP代币提供的代币数量,计算特定的用户可以获得多少token,如下图:

这里非常重要的一点是:

整个奖励计算流程中,只要user.token0Rewards奖励计算出来后,如果不提取奖励,该值不会再受到减少的影响,只可能通过fee0Earned方法更新不断增大。

攻击流程到这里就比较清晰了,攻击者合约1将LP转至攻击者合约2后,攻击者合约2随即调用漏洞合约的collectFees方法更新奖励值,随后将LP转出,由于user.token0Rewards奖励值只会叠加,并且该方法中并未判断调用者是否拥有LP,之后攻击者合约2再次调用collectFees方法获取user.token0Rewards奖励。

从以上攻击流程可以看出,攻击者利用SorbettoFragola合约未判断LP的归属问题,借助闪电贷资金,多地址移动LP并调用collectFees方法,多次循环操作后,获取大量代币。

总结

通过此次攻击事件来看,攻击者通过闪电贷资金,并通过SorbettoFragola合约未判断LP的归属问题,最终获得了大量代币,目前类似的闪电贷攻击事件居多,为何还会频频发生,对于DeFi项目而言,合约代码的安全,代币价格的相对稳定,旧版本的及时更新都是保证项目安全极其重要的部分,对于合约未判断LP的归属问题,应在合约上线前进行严格审查及测试。对于此类闪电贷攻击事件,零时科技安全团队给出以下建议:

安全建议

  • 对于合约代码安全,可找多家安全审计公司进行审计。

  • 对LP归属及获取奖励判断,应根据业务逻辑进行严格审核演算,避免出现参数可控导致盗币问题。

  • 对转账地址应进行严格判断,避免转账地址异常导致参数可控。

  • 使用可信的并且安全可靠的预言机,如Chainlink去中心化预言机,Alpha homera采用的。

  • 对敏感性较强的代码,要做到及时更新完善。

这篇关于Popsicle攻击事件复盘分析 | 零时科技的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/342878

相关文章

Go标准库常见错误分析和解决办法

《Go标准库常见错误分析和解决办法》Go语言的标准库为开发者提供了丰富且高效的工具,涵盖了从网络编程到文件操作等各个方面,然而,标准库虽好,使用不当却可能适得其反,正所谓工欲善其事,必先利其器,本文将... 目录1. 使用了错误的time.Duration2. time.After导致的内存泄漏3. jsO

C#如何动态创建Label,及动态label事件

《C#如何动态创建Label,及动态label事件》:本文主要介绍C#如何动态创建Label,及动态label事件,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#如何动态创建Label,及动态label事件第一点:switch中的生成我们的label事件接着,

Spring事务中@Transactional注解不生效的原因分析与解决

《Spring事务中@Transactional注解不生效的原因分析与解决》在Spring框架中,@Transactional注解是管理数据库事务的核心方式,本文将深入分析事务自调用的底层原理,解释为... 目录1. 引言2. 事务自调用问题重现2.1 示例代码2.2 问题现象3. 为什么事务自调用会失效3

找不到Anaconda prompt终端的原因分析及解决方案

《找不到Anacondaprompt终端的原因分析及解决方案》因为anaconda还没有初始化,在安装anaconda的过程中,有一行是否要添加anaconda到菜单目录中,由于没有勾选,导致没有菜... 目录问题原因问http://www.chinasem.cn题解决安装了 Anaconda 却找不到 An

Spring定时任务只执行一次的原因分析与解决方案

《Spring定时任务只执行一次的原因分析与解决方案》在使用Spring的@Scheduled定时任务时,你是否遇到过任务只执行一次,后续不再触发的情况?这种情况可能由多种原因导致,如未启用调度、线程... 目录1. 问题背景2. Spring定时任务的基本用法3. 为什么定时任务只执行一次?3.1 未启用

C++ 各种map特点对比分析

《C++各种map特点对比分析》文章比较了C++中不同类型的map(如std::map,std::unordered_map,std::multimap,std::unordered_multima... 目录特点比较C++ 示例代码 ​​​​​​代码解释特点比较1. std::map底层实现:基于红黑

Spring、Spring Boot、Spring Cloud 的区别与联系分析

《Spring、SpringBoot、SpringCloud的区别与联系分析》Spring、SpringBoot和SpringCloud是Java开发中常用的框架,分别针对企业级应用开发、快速开... 目录1. Spring 框架2. Spring Boot3. Spring Cloud总结1. Sprin

Spring 中 BeanFactoryPostProcessor 的作用和示例源码分析

《Spring中BeanFactoryPostProcessor的作用和示例源码分析》Spring的BeanFactoryPostProcessor是容器初始化的扩展接口,允许在Bean实例化前... 目录一、概览1. 核心定位2. 核心功能详解3. 关键特性二、Spring 内置的 BeanFactory

MyBatis-Plus中Service接口的lambdaUpdate用法及实例分析

《MyBatis-Plus中Service接口的lambdaUpdate用法及实例分析》本文将详细讲解MyBatis-Plus中的lambdaUpdate用法,并提供丰富的案例来帮助读者更好地理解和应... 目录深入探索MyBATis-Plus中Service接口的lambdaUpdate用法及示例案例背景

MyBatis-Plus中静态工具Db的多种用法及实例分析

《MyBatis-Plus中静态工具Db的多种用法及实例分析》本文将详细讲解MyBatis-Plus中静态工具Db的各种用法,并结合具体案例进行演示和说明,具有很好的参考价值,希望对大家有所帮助,如有... 目录MyBATis-Plus中静态工具Db的多种用法及实例案例背景使用静态工具Db进行数据库操作插入